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

发布于 2024-12-09 23:42:00 字数 575 浏览 1 评论 0原文

我一直在尝试使用free()释放通过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;
}

I have been trying to free memory allocated via malloc() using free().

Some of the structs it does free but leaves some the way they were and they also remain linked to their children. It also never frees the root (gRootPtr) for a binary tree.

I am using Xcode to find out if the memory used by the binary tree has been freed and also use the if statement.

Code I am using to free the memory:

void FreeMemory(InfoDefiner *InfoCarrier)
{
    if ((*InfoCarrier) != NULL) {
        FreeMemory((&(*InfoCarrier)->left));
        FreeMemory((&(*InfoCarrier)->right));
        free((*InfoCarrier));
    }
}

Code I am using to see if the memory has been freed.

if (gRootPtr != NULL) {
    return 1;
}
else{
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

╰沐子 2024-12-16 23:42:00

首先,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() 是合法的(当然,如果是这种情况,您最终会耗尽内存)。

First, free does not change the pointer itself.

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

If you want the pointer to go back to NULL, you must do this yourself.

Second, there are no guarentees about what will happen to the memory pointed to by the pointer after the 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!

Note that this means that you cannot actually test if free() works. Strictly speaking, it's legal for free() to be implemented by doing absolutely nothing (although you'll run out of memory eventually if this is the case, of course).

呆萌少年 2024-12-16 23:42:00

该检查不会检查变量是否已释放。请注意,free(pointer) 不会将该指针设置为 NULL。如果您希望出现这种情况,则必须自己设置它,这是 C 中的常见习惯用法:

free(pointer);
pointer = NULL;

表示您已经释放了该指针。

That check won't check if the variable is freed. Note that free(pointer) does not set that pointer to NULL. If you want that to be the case, you have to set it yourself, and it is a common idiom in C:

free(pointer);
pointer = NULL;

to signal that you already freed that pointer.

我还不会笑 2024-12-16 23:42:00

调用 free 不会将指针设置为 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.

Calling free does not set the pointer to NULL. You have to do that yourself.

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.
蛮可爱 2024-12-16 23:42:00

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

为此,最好在释放指针后重新初始化它们。这可以让您:

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

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

通过测试看看是否指针已初始化(或 NULL)。

最好手动执行此操作并养成这样做的习惯。我见过一些非常复杂的重新实现free()的方法,以便自动重新初始化指针,就像这个小宝石一样,它也尝试避免释放不属于“的内存” t allocate:

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

不要使用该代码,由于取消引用类型双关指针,它会在严格的平台上严重崩溃。另外,如果指针是字符串文字怎么办?

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

The only reason free() would fail is if the pointer you give it does not dereference to allocated heap. This behavior is clearly defined, free() will either work, or your program will halt due to an access violation.

It is good practice to re-initialize your pointers after freeing them, for just this purpose. This lets you:

  • Make sure you don't allocate on top of an already allocated pointer (thus losing the reference to the original blocks and causing a leak) (realloc() notwithstanding).

  • Make sure you don't free recently freed memory, or memory that was never allocated

Both become easy by testing to see if the pointer is initialized (or, NULL).

It's best to just do this manually and get in the habit of doing so. I have seen some very convoluted ways of re-implementing free() so that re-initializes the pointer automatically, like this little gem that also attempts avoid freeing memory that wasn't allocated:

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

Please, don't use that code, it will break horribly on strict platforms due to dereferencing a type punned pointer. Additionally, what if the pointer is a string literal?

Instead, just make sure you keep track of your pointers and initialize them after freeing.

亽野灬性zι浪 2024-12-16 23:42:00

函数free需要一个指向已分配内存的指针,但是它不会将该指针设置为NULL,事实上它无法这样做(它需要采取指针的地址)。

此场景的典型用例是:

free(myptr);
myptr = NULL;

The function free takes a pointer to allocated memory, it does not however set that pointer to NULL, in fact there is no way it could do so (it would need to take the address of a pointer for that).

Typical use case in this scenario is:

free(myptr);
myptr = NULL;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文