c - 这是释放内存的好方法吗?

标签 c memory free

释放struct Foo实例的函数如下:

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

我的一位同事提出了以下建议:

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 更好,但我不确定以下内容:

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

  2. 将整个 block 设置为 0 以强制程序崩溃或至少输出具有显着差异的结果真的是个好主意吗?

最佳答案

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

它与并发或共享内存无关。没意义。

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?

没有。一点也不。

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

  • 将整个 block 设置为 0 也无济于事。因为有人不小心使用了 free() 的 block ,所以他们不会根据 block 上的值知道这一点。这就是 calloc() 返回的那种 block 。 所以不可能知道它是新分配的内存(calloc()malloc()+memset())还是你的代码已经 free()'ed早些时候。如果有的话,你的程序需要额外的工作来清零每个被 free()'ed 的内存块。

  • free(NULL); 是明确定义的并且是无操作的,所以 if(ptr) {free (ptr);} 一无所获。

  • 由于 free(NULL); 是无操作的,将指针设置为 NULL 实际上会隐藏该错误,因为如果某个函数实际上正在调用 free() 在一个已经 free() 的指针上,那么他们就不会知道了。

  • 大多数用户函数在开始时都会进行 NULL 检查,并且可能不会将 NULL 视为错误条件:

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

   /*Do something with ptr here */
}

因此,所有这些额外的检查和归零给人一种虚假的“鲁棒性”感,但并没有真正改善任何东西。它只是用额外的性能成本和代码膨胀代替了一个问题。

所以在没有任何包装函数的情况下调用 free(ptr); 既简单又健壮(大多数 malloc() 实现会在双重释放时立即崩溃,这是一个好东西)。

“不小心”调用 free() 两次或更多次没有简单的方法。跟踪所有分配的内存并适本地 free() 是程序员的责任。如果有人觉得这很难处理,那么 C 可能不是适合他们的语言。

关于c - 这是释放内存的好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34651234/

相关文章:

c 的自定义 malloc 函数

c - 释放大数组指针时出现段错误

c - C语言中如何获取内存地址并输出?

c - 仅使用 1 次递归调用的斐波那契数列 C

memory - Redis RSS 2.7GB 和增加。使用的内存只有 40MB。为什么?

c++ - 如何通过 C++ 检索已提交的内存

c++ - 修剪延迟空闲队列时堆损坏

c - 如何计算 C 中信号或结构所需的内存

c - 没有接收到数据,recv()返回0

c++ - 三角形二维数组比矩形数组占用更多内存