C中的函数free()对我不起作用

我一直在尝试使用free()通过malloc()分配的malloc()

它的一些结构是免费的,但它们保留了一些它们的方式,它们也与它们的孩子保持联系。 它也永远不会释放二进制树的根(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; } 

首先,free不会改变指针本身。

 void *x = malloc(1); free(x); assert(x != NULL); // x will NOT return to NULL 

如果希望指针返回NULL,则必须自己执行此操作。

其次,没有关于free之后指针所指向的内存会发生什么的保证:

 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()是合法的free()当然,如果情况确实如此,你最终会耗尽内存)。

该检查不会检查变量是否被释放。 请注意, free(pointer)不会将该指针设置为NULL。 如果你想要那样,你必须自己设置它,这是C中常见的习语:

 free(pointer); pointer = NULL; 

表示你已经释放了指针。

调用free不会将指针设置为NULL 。 你必须自己做。

  7.21:调用free()后为什么指针不为null?
    之后使用(赋值,比较)指针值有多不安全
    它已被释放?

答:当你调用free()时,传递的内存指向的内存
    指针被释放,但调用者中的指针值
    可能保持不变,因为C的传值值语义
    意味着被调用的函数永远不会永久地更改值
    他们的论点。  (另见问题4.8。)

    严格来说,已释放的指针值是
    无效,*任何*使用它,即使它没有被解除引用,
    理论上可以导致麻烦,虽然作为一种品质
    实施问题,大多数实现可能不会去
    他们的方式为无害的使用产生例外
    无效的指针。

    参考文献:ISO Sec。  7.10.3; 基本原理  3.2.2.3。 

free()失败的唯一原因是你给它的指针不会取消引用已分配的堆。 此行为已明确定义, free()将起作用,或者您的程序将因访问冲突而暂停。

为了这个目的,最好在释放指针后重新初始化指针。 这可以让你:

  • 确保不在已分配的指针之上进行分配(从而丢失对原始块的引用并导致泄漏)(尽管realloc())。

  • 确保您没有释放最近释放的内存或从未分配的内存

通过测试以查看指针是否已初始化(或NULL),两者都变得容易。

最好是手动完成此操作并养成这样做的习惯。 我已经看到了一些非常复杂的重新实现free()以便自动重新初始化指针,就像这个小gem一样,也试图避免释放未分配的内存:

 void safe_free(void **p) { if (*p != NULL) { free(*p); *p = NULL; } } 

不要使用该代码,由于取消引用类型的惩罚指针,它将在严格的平台上破坏。 另外,如果指针是字符串文字怎么办?

相反,只需确保跟踪指针并在释放后初始化它们。

函数free接受一个指向已分配内存的指针,但它不会将该指针设置为NULL ,实际上它没有办法可以这样做(它需要获取指针的地址)。

此方案中的典型用例是:

 free(myptr); myptr = NULL;