[英]C dynamic struct (malloc and free)
我正在尝试学习C,C ++编程的基础知识,所以我从“C”开始。 我有很多使用Java和VB编程的经验。 但“C”是我想学的东西。 所以我遇到了一个问题,试图理解“malloc”和“free”函数。
我在Windows 98上使用Borland C ++ 4.5和Visual C ++ 6.0。 - (只是一个测试环境,想学习非常基础和早期的Windows编程)。
请参阅此代码:
struct String
{
char *value;
int length;
};
char *initString(const char *value)
{
char *str = (char*)malloc( strlen(value)+1 );
strcpy(str, value);
return str;
}
struct String *InitString(const char *text)
{
struct String *str = (struct String*)malloc( sizeof(struct String) );
str->value = initString(text);
str->length = strlen( str->value );
return str;
}
void freeString(struct String *str)
{
free(str->value);
free(str);
str = NULL;
}
int main(int argv, char *argc[])
{
struct String *theString = InitString("Testring string struct");
printf("String: %s\n", theString->value);
printf("String Length: %d\n", theString->length);
freeString(theString);
printf("\nData: %s", theString->value);
return 0;
}
该程序运行时,结果是正确的。
在我调用“ freeString(theString)
”之后,该函数释放内存并在“freeString()”函数内将结构设置为NULL,当我传入指针时,该函数应释放“main()”中的“theString”到“theString”,但是当函数返回时:“theString”不是“NULL”。
在Borland 4.5上,我仍然可以使用“theString-> value”调用“printf”并打印字符串。 在Visual C ++上,程序在调用“printf”时崩溃 - 但“theString”仍然不是“NULL”。 当我在调试模式下跟踪程序时,“struct”在“freeString()”函数内被释放,并且struct被设置为NULL,但是当函数返回时,“theString”不是NULL并且“value”是仍可用于Borland,但不能用于Visual C ++。
所以我想了解,这里发生了什么? 是否应该进行一些去引用?
先感谢您!
这是你永远不应该在它指向的内存被释放后使用指针的原因之一。 行为是未定义的,这正是您在这里看到的。
你正在看未定义的行为 (你在免费后使用了一个值),所以真的 - 任何事情都可能发生。 它可能会崩溃,或者它可以“正常”运行
可能发生的事情是msvc,至少在调试模式下,将特殊字节模式归零或写入你释放的内存,这样str->值指针变为无效并在你取消引用它时崩溃,而borland只是将内存释放回内存游泳池,但没有动摇。
你的str=NULL
在函数中
void freeString(struct String *str)
{
free(str->value);
free(str);
str = NULL;
}
没有实际效果。 它只是将本地str
值设置为NULL,调用者不受影响。
如果要将调用者的指针设置为NULL,则必须传入指向该指针的指针,或者在C ++的情况下,传递对指针的引用。
void freeString(struct String *&str) //c++
{
free(str->value);
free(str);
str = NULL;
}
void freeString(struct String **str) //c, call it as freeString(&theString);
{
free((*str)->value);
free(*str);
*str = NULL;
}
C是按值调用的。 如果调用freeString(anotherFunction(theString))
会被设置为NULL
?
如果要让函数对该指针的引用具有副作用,则必须传入指向指针的指针。
惯用C99只会在freeString()
省略str = NULL
的赋值。
实际上谁必须传递参数的指针而不仅仅是指针的地址
void freeString( struct String **str)
{
...
*str=NULL;
}
否则你将指针str的副本设置为NULL而不是str本身...
并进入main()不要忘记测试NULL指针以避免崩溃:
if (theString!=NULL)
printf("\nData: %s", theString->value);
您正在尝试访问已发布的字段。 这导致了不确定的行为。 尽管在某些编译器上发布了该值,您仍然可以访问该值,因为该特定字段不会被任何其他正在运行的应用程序重置。 即使在X-Code上,这也很愉快,但在Visual Studio Compiler上却没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.