【问题标题】:What happens if you set a pointer to NULL before freeing the memory?如果在释放内存之前将指针设置为 NULL 会发生什么?
【发布时间】:2021-01-20 21:17:12
【问题描述】:

从安全的角度来看,在释放内存后将指针设置为 NULL 据说是一种很好的做法。如果在释放内存之前将指针设置为 NULL 会发生什么?这将如何导致漏洞?

【问题讨论】:

  • 不会造成安全漏洞,只会造成内存泄漏。这仅意味着如果您有太多内存泄漏,您的程序可能会终止。
  • 旁注: 将 [freed] 指针设置为 NULL 是一种很好的做法,原因有很多。 (1) 尽管您永远不应该在指针被释放后释放它,但将其归零会将第二个 free 变成“危害较小”的东西 [因为 free 忽略空值](与“双重释放”中止free)。 (2) 你不应该在指针被释放后取消引用/使用它,但是如果出现错误:(例如)free(ptr); val = *ptr;,这会产生 UB/不正确的结果 [静默]。执行free(ptr); ptr = NULL; val = *ptr; 会导致错误的 deref 出现段错误,因此会注意到错误。
  • 如果在传递给free 之前将指针设置为空,那么free 怎么知道要释放什么?

标签: c pointers nullpointerexception nullreferenceexception dereference


【解决方案1】:

我认为您误解了释放内存后将其设置为NULL 的原因。你不想触碰不属于你的记忆。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *a = malloc(sizeof(int));
    free(a);
    printf("%p", a);
    *a = 1;
    return 0;
}

我们释放了指针,但它仍然指向同一个地址。我可以写信给它“没问题”。实际上,在这种情况下,您会遇到未定义的行为。

因此,如果您释放指针并在以后使用它,您将面临灾难。但是如果你把它设置为NULL,那么你就会出现段错误。就像在这种情况下一样。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *a = malloc(sizeof(int));
    free(a);
    printf("%p", a);
    a = NULL;
    *a = 1;
    return 0;
}

因此,如果您取消引用一个已释放的指针,至少您会在测试应用程序时确定地了解它。

现在如果你在释放内存之前将它设置为 NULL,你只会泄漏内存。还是很糟糕。

【讨论】:

  • 在第二个示例中,将指针设置为 NULL 并不能保证段错误。取消引用 NULL 指针也是未定义的行为,因此段错误只是一种可能的结果。
  • 没错,它几乎是实现定义的。我不知道,我认为如果你取消引用 NULL,你总是会出现段错误。 I think this answer explains it really well. 感谢您指出@Blastfurnace。
【解决方案2】:

如果在释放内存之前将指针设置为 NULL 会发生什么?

如果你试图释放一个空指针,什么都不会发生。

如果有其他指针指向同一个内存,它们可以继续被用来引用并最终释放内存。

如果这是指向该内存的唯一指针,则无法再次引用该内存。该进程将保留内存直到它退出。这是“内存泄漏”。

存在内存泄漏的进程将使用越来越多的内存。泄漏很常见,以至于长时间运行的进程甚至整个服务器都习惯性地每天重新启动。

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 2015-05-25
    • 2013-07-30
    • 2016-03-01
    • 2019-06-17
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 2010-12-25
    相关资源
    最近更新 更多