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

时间:2011-10-14 23:00:04

标签: c malloc free std

我一直尝试使用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;
}

5 个答案:

答案 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;