释放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
更好,但我不确定以下内容:
我们真的需要将指针分配给一个临时的吗?它在并发和共享内存方面有帮助吗?
将整个 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/