这是释放内存的好方法吗? [英] Is this a good way to free memory?

查看:96
本文介绍了这是释放内存的好方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

释放struct Foo实例的功能如下:

void DestroyFoo(Foo* foo)
{
    if (foo) free(foo);
}

我的一位同事建议以下内容:

A colleague of mine suggested the following instead:

void DestroyFoo(Foo** foo)
{
    if (!(*foo)) return;
    Foo *tmpFoo = *foo;
    *foo = NULL; // prevents future concurrency problems
    memset(tmpFoo, 0, sizeof(Foo));  // problems show up immediately if referred to free memory
    free(tmpFoo);
}

我看到释放后将指针设置为NULL更好,但是我不确定以下内容:

I see that setting the pointer to NULL after freeing is better, but I'm not sure about the following:

  1. 我们真的需要将指针分配给一个临时指针吗?在并发和共享内存方面有帮助吗?

  1. Do we really need to assign the pointer to a temporary one? Does it help in terms of concurrency and shared memory?

将整个块设置为0是真的好主意,以迫使程序崩溃或至少输出具有明显差异的结果吗?

Is it really a good idea to set the whole block to 0 to force the program to crash or at least to output results with significant discrepancy?

推荐答案

我们真的需要将指针分配给一个临时指针吗?可以 并发和共享内存方面有帮助吗?

Do we really need to assign the pointer to a temporary one? Does it help in terms of concurrency and shared memory?

它与并发或共享内存无关.这是没有意义的.

It has nothing to do concurrency or shared memory. It's pointless.

将整个块设置为0强制使用 程序崩溃或至少输出具有重大意义的结果 差异?

Is it really a good idea to set the whole block to 0 to force the program to crash or at least to output results with significant discrepancy?

不.完全没有.

您的同事建议的解决方案很糟糕.原因如下:

The solution suggested by your colleague is terrible. Here's why:

  • 将整个块设置为0也不会有任何效果.因为有人不小心使用了free()块,所以基于该块的值,他们不会知道这一点.这就是calloc()返回的块. 因此,不可能知道它是刚分配的内存(calloc()malloc()+memset())还是您的代码先前由free()分配的内存.如果有的话,对您的程序来说,将free()编辑的每个内存块清零是多余的工作.

  • Setting whole block to 0 achieves nothing either. Because someone is using a free()'ed block accidentally, they wouldn't know that based on the values at the block. That's the kind of block calloc() returns. So it's impossible to know whether it's freshly allocated memory (calloc() or malloc()+memset()) or the one that's been free()'ed by your code earlier. If anything it's extra work for your program to zero out every block of memory that's being free()'ed.

free(NULL);是定义明确的并且是无操作的,因此if(ptr) {free(ptr);}中的if条件什么都没有实现.

free(NULL); is well-defined and is a no-op, so the if condition in if(ptr) {free(ptr);} achieves nothing.

由于free(NULL);是空操作,因此将指针设置为NULL实际上会隐藏该错误,因为如果某些函数实际上是在已经具有free()的指针上调用free(),则它们不知道.

Since free(NULL); is no-op, setting the pointer to NULL would actually hide that bug, because if some function is actually calling free() on an already free()'ed pointer, then they wouldn't know that.

大多数用户功能在开始时都会进行NULL检查,并且可能不考虑将NULL作为错误条件传递给它:

most user functions would have a NULL check at the start and may not consider passing NULL to it as error condition:

void do_some_work(void *ptr) {
    if (!ptr) {
        return; 
    }

   /*Do something with ptr here */
}

因此,所有这些额外的检查和归零都会给人一种健壮"的假象,而实际上并没有任何改善.它只是将一个问题替换为另一个问题,而这又增加了性能和代码膨胀的成本.

So the all those extra checks and zero'ing out gives a fake sense of "robustness" while it didn't really improve anything. It just replaced one problem with another the additional cost of performance and code bloat.

因此,仅调用free(ptr);而没有任何包装函数既简单又健壮(大多数malloc()实现会在两次释放时立即崩溃,这是一件很不错的事情).

So just calling free(ptr); without any wrapper function is both simple and robust (most malloc() implementations would crash immediately on double free, which is a good thing).

没有简单的方法可以意外"调用free()两次或两次以上.跟踪所有分配的内存并适当地free()是程序员的责任.如果有人觉得这很难处理,那么C可能不是适合他们的语言.

There's no easy way around "accidentally" calling free() twice or more. It's the programmer's responsibility to keep track of all memory allocated and free() it appropriately. If someone find this hard to handle then C is probably not the right language for them.

这篇关于这是释放内存的好方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆