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

C 什么是;“双重免费”;什么意思?,c,double-free,C,Double Free,正如标题所示,我是C的新手,很快就会有一个期中考试。我现在正在修改过去的论文,一个反复出现的主题是双重自由问题。我知道这是在同一个内存位置上调用两次free()的过程,但我有几个问题无法100%确定如何回答: 问题1:C中双自由度的结果是什么,为什么会出现这样的问题? 这将导致双重自由: char* ptr = malloc(sizeof(char)); *ptr = 'a'; free(ptr); free(ptr); 我对此的反应是,它会返回0x0内存地址并导致系统不稳定/崩溃。另外,如

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

问题1:C中双自由度的结果是什么,为什么会出现这样的问题?

这将导致双重自由:

char* ptr = malloc(sizeof(char));

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

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

问题2:描述一种特别容易引入 双自由度C?

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


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

从技术上讲,C中的双自由度会导致未定义的行为。这意味着程序可以完全任意地运行,所有关于所发生的事情的赌注都是无效的。发生这种事真是件坏事!实际上,双重释放内存块将损坏内存管理器的状态,这可能会导致现有内存块损坏,或导致将来的分配以奇怪的方式失败(例如,在两次不同的连续调用
malloc
)时分发相同的内存)

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


希望这有帮助

根据已发布的C11标准,对已存在的
free
内存位置调用
free
会导致未定义的行为。它可能会导致一些奇怪的情况,例如内存即使可用也无法分配,堆损坏,相同的内存位置分配给不同的malloc等等。基本上,它是未定义的,可以是任何东西

ANSI C11标准可在此处找到


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

,因为free()将通过管理存储在每个区域之前的标记中的信息来合并相邻区域。这有点像管理双链接列表。因此,如果
ptr
所指向的缓冲区被攻击字符串覆盖,这将是危险的,在攻击字符串中可以注入假标记。

这个问题已经得到了很好的回答,但我添加了一个延迟回答,因为有一个“重复问题”链接,它询问“如何避免它?”

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

char* ptr = malloc(sizeof(char));

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

函数
free
NULL
指针不执行任何操作。

“…它会返回0x0内存地址吗…”
-这是怎么回事?什么会返回0x0内存地址?函数
free
不返回任何内容。双重免费漏洞有时可能是非常严重的安全漏洞-下面是一个例子:我在C中发现了一堆未定义的行为,因此我希望这些行为符合我的预期。由于这个原因,我想建议单/双链接列表可能非常容易受到双重免费的影响,谢谢你的回答。你从哪里找到这些信息的?(“在空指针上调用free会导致未定义的行为。”)这是不正确的。“Double free”和“free on NULL”是两个独立的问题。前者是未定义的行为,但后者是无害的禁止操作。你确定这是正确的吗?我提到的ISO标准草案明确表示,对空指针调用
free
无效。我很抱歉。我的错。意味着双重自由。对原始答案进行了一些编辑。@templatetypedef username也会签出。这只在只有一个指向内存块的指针的简单情况下有用。在更常见的情况下,有多个指针指向同一个内存,这要复杂得多。