在 free() 之后将指针设置为 NULL 总是一个好习惯吗? [复制]

Posted

技术标签:

【中文标题】在 free() 之后将指针设置为 NULL 总是一个好习惯吗? [复制]【英文标题】:Is it always a good practice to set pointers to NULL after free()-ing them? [duplicate] 【发布时间】:2011-03-22 21:37:25 【问题描述】:

可能重复:Setting variable to NULL after free …

我正在学习良好的 C 编程实践,我的朋友告诉我在释放指针(或调用特定的释放函数)后总是将指针设置为 NULL。

例如:

char* ptr = malloc(100);
...
free(ptr);
ptr = NULL;

struct graph* graph = create_graph();
...
destroy_graph(graph);
graph = NULL;

为什么这是一个好的做法?

更新:阅读答案后,这对我来说似乎是一种糟糕的做法!我隐藏了可能的 double-free() 错误。这怎么可能是一个好习惯?我很震惊。

谢谢,博达·赛多。

【问题讨论】:

@bodacydo 看看页面右侧的“相关”问题。 怎么样?释放指针并将其设置为 NULL 可以释放内存。如果你决定释放 NULL,你应该得到一个断言或其他警告。双重释放内存比释放 NULL 更难跟踪。 如果你释放 NULL 它默默地什么都不做,你不会得到断言。这是一件好事,因为它使清理代码更容易,您需要更少的 if;但我至少可以从“隐藏错误”的角度看到 OP 的来源。 @bodacydo:它隐藏了双重释放,但不这样做可能会隐藏野指针错误(在内存被释放后访问指针)。这是一个权衡,所以它不一定是坏的(但不一定是好的)。就我个人而言,我不认为多余的空指针一定是错误,但访问野指针总是是错误的,所以我支持分配给NULL 我相信逻辑是双释放是一个较小的错误,它实际上使用了已释放的内存。假设您在一台机器上,其中取消引用 NULL 会引发一个信号,您很快就会发现一个严重的错误。 【参考方案1】:

我的不良做法投票。如果您确实想要分配一个值,请将其设置为 (void*)0xdeadbeef。不过,请先检查您的 CRT 可以做什么。一个体面的调试分配器会将释放的内存设置为一个模式,当指针在被释放后使用时可能会导致炸弹。虽然不能保证。但是改变指针值是更好(更快)的解决方案。

【讨论】:

【参考方案2】:

虽然不会造成伤害,但并不总是有帮助。要考虑的问题是指针很容易有多个副本,并且很可能您只会将一个副本设置为 NULL。它根本没有帮助的典型例子是:

void free_graph(graph *g)

    ...
    free(g);
    g = NULL;  // not useful in this context

这里的问题是,您只是将free_graph 的本地指针设置为NULL,而free_graph 的调用者持有的指针仍然具有它的原始值。

【讨论】:

【参考方案3】:

这被一些人认为是一种很好的做法,因为它可以防止您在内存被 free() 后意外访问内存。

【讨论】:

阅读答案后,我发现这是一种不好的做法-我隐藏了双重免费的错误!这怎么可能是一个好的做法? 实际上,它不会自动阻止您访问它,但您可以(并且应该)始终检查 NULL 指针,但您无法判断非 NULL 指针是否有效。因此,这是一种很好的做法。 我还不相信这是一个好习惯。【参考方案4】:

我认为是的……

当你使用完一部分 menory 后,我们应该 free() 它。这允许释放的内存用于其他目的……比如进一步的 malloc() 调用。

Free 将指向内存的指针作为参数,并释放指针所指的内存...

希望这会有所帮助... :)

【讨论】:

-1:这不能回答问题。 bodacydo 没有问,他是否应该释放记忆。他在问,是否应该在释放指针后将指针设置为 NULL。

以上是关于在 free() 之后将指针设置为 NULL 总是一个好习惯吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥free函数不在释放内存后,将指针置NULL,野指针有啥用

free() 在 c 代码和代码中收集垃圾值即使在释放后将指针设置为 NULL 也不起作用

字符指针用free释放后,需要设置null吗?

求助 一个指针被free之后啥时候是NULL?还是不可能是NULL?

C语言中free掉一段空间后为啥还要使用NULL

C语言中, 为了避免野指针,是否可以在free和delete之后,把指针置为NULL就可以避免了?