我一直尝试使用malloc()
释放通过free()
分配的内存。
它的一些结构是免费的,但它们保留了它们的方式,它们也与它们的孩子保持联系。它也永远不会为二叉树释放根(gRootPtr)
。
我正在使用Xcode来查明二叉树使用的内存是否已被释放,并使用if语句。
我用来释放内存的代码:
void FreeMemory(InfoDefiner *InfoCarrier)
{
if ((*InfoCarrier) != NULL) {
FreeMemory((&(*InfoCarrier)->left));
FreeMemory((&(*InfoCarrier)->right));
free((*InfoCarrier));
}
}
我正在使用的代码来查看内存是否已被释放。
if (gRootPtr != NULL) {
return 1;
}
else{
return 0;
}
答案 0 :(得分:16)
首先,free不会更改指针本身。
void *x = malloc(1);
free(x);
assert(x != NULL); // x will NOT return to NULL
如果希望指针返回NULL,则必须自己执行此操作。
其次,没有关于免费后指针所指向的内存会发生什么的保证:
int *x = malloc(sizeof(int));
*x = 42;
free(x);
// The vlaue of *x is undefined; it may be 42, it may be 0,
// it may crash if you touch it, it may do something even worse!
请注意,这意味着如果free()
有效,无法实际测试。严格来说,free()
通过绝对不做任何事情来实现是合法的(尽管如果情况确实如此,你最终会耗尽内存)。
答案 1 :(得分:5)
检查不会检查变量是否已被释放。请注意,free(pointer)
未将该指针设置为NULL。如果您希望如此,您必须自己设置,这是C中常见的习语:
free(pointer);
pointer = NULL;
表示您已经释放了该指针。
答案 2 :(得分:2)
Calling free does not set the pointer to NULL。你必须自己做。
7.21: Why isn't a pointer null after calling free()? How unsafe is it to use (assign, compare) a pointer value after it's been freed? A: When you call free(), the memory pointed to by the passed pointer is freed, but the value of the pointer in the caller probably remains unchanged, because C's pass-by-value semantics mean that called functions never permanently change the values of their arguments. (See also question 4.8.) A pointer value which has been freed is, strictly speaking, invalid, and *any* use of it, even if it is not dereferenced, can theoretically lead to trouble, though as a quality of implementation issue, most implementations will probably not go out of their way to generate exceptions for innocuous uses of invalid pointers. References: ISO Sec. 7.10.3; Rationale Sec. 3.2.2.3.
答案 3 :(得分:2)
free()
失败的唯一原因是你指定的指针不会取消引用已分配的堆。此行为已明确定义,free()
将起作用,或者您的程序将因访问冲突而暂停。
为了这个目的,最好在释放指针后重新初始化指针。这让你:
确保不在已分配的指针之上进行分配(从而丢失对原始块的引用并导致泄漏)(尽管有realloc())。
确保您没有释放最近释放的内存或未分配的内存
通过测试以查看指针是否已初始化(或为NULL),两者都变得容易。
最好是手动完成此操作并养成这样做的习惯。我已经看到了一些非常复杂的重新实现free()
的方法,以便自动重新初始化指针,就像这个小宝石一样,也试图避免释放未分配的内存:
void safe_free(void **p)
{
if (*p != NULL) {
free(*p);
*p = NULL;
}
}
请不要使用该代码,由于取消引用类型的惩罚指针,它将在严格的平台上崩溃。另外,如果指针是字符串文字怎么办?
相反,只需确保跟踪指针并在释放后初始化它们。
答案 4 :(得分:1)
函数free
获取指向已分配内存的指针,但它不会将该指针设置为NULL
,实际上它没有办法可以这样做(它需要取地址一个指针)。
此方案中的典型用例是:
free(myptr);
myptr = NULL;