“双重免费”是什么意思?

正如标题所暗示的那样,我是C的新手并且很快就会出现中期。 我正在修改过去的论文,反复出现的主题是双重免费问题。 我知道这是在同一个内存位置上调用free()两次的过程,但我有几个问题,我不是100%肯定如何回答:

问题1:C中双重释放的结果是什么,为什么会出现这样的问题?

这将导致双倍免费:

 char* ptr = malloc(sizeof(char)); *ptr = 'a'; free(ptr); free(ptr); 

我对此的回应是,它会返回0x0内存地址并导致系统不稳定/崩溃。 另外,如果我没记错的话,double free实际上可以调用malloc两次,这会导致缓冲区溢出,从而使系统容易受到攻击。

简要总结这个问题的最佳方法是什么?

问题2:描述一种特别容易在C中引入双重免费的情况?

我在想当你绕过指针时可能会意外地将它释放到一个函数中,并且在没有意识到的情况下再次释放它?

再说一次,总结这个的“最佳”方法是什么?

从技术上讲,C中的双重自由会导致不确定的行为 。 这意味着该程序可以完全随意地运行,所有投注都不会发生。 发生这当然是件坏事! 在实践中,双重释放内存块将破坏内存管理器的状态,这可能导致现有的内存块被破坏或者未来的分配以奇怪的方式失败(例如,相同的内存分配给两个malloc不同连续调用)。

在各种情况下都可能发生双重释放。 一个相当常见的是当多个不同的对象都有指向彼此的指针并开始通过调用free来清理。 发生这种情况时,如果您不小心,在清理对象时可能会多次free相同的指针。 不过,还有很多其他案例。

希望这可以帮助!

因为free()将通过在每个区域之前管理存储在标签中的信息来合并相邻区域。 这就像管理双链表一样。 因此,如果ptr指向的缓冲区已被攻击字符串覆盖,那么将会注入假标记,这将是危险的。

这个问题已得到很好的解答,但由于“重复问题”链接,我提出了一个迟到的答案,该链接询问“如何避免它?”

一行添加到发布的示例代码中。

 char* ptr = malloc(sizeof(char)); *ptr = 'a'; free(ptr); ptr = NULL; // add this free(ptr); 

函数freeNULL指针不起作用。

根据已发布的C11标准,在已经free内存位置上调用free会导致未定义的行为。 它可能会导致奇怪的情况,例如内存即使在可用时也没有被分配,堆变得腐败,相同的内存位置被分配给不同的mallocs等。基本上,它是未定义的,可以是任何东西。

ANSI C11标准可以在这里找到。 https://www.iso.org/obp/ui/#iso:std:iso-iec:9899:ed-3:v1:en

编辑:根据评论将NULL更改为已free d。 另外,链接现在指向ISO / IEC 9899:2011(en)