使用realloc是否安全?

时间:2012-01-30 22:11:03

标签: c memory-leaks memory-management realloc

前段时间我的一位朋友告诉我不要使用realloc,因为它不安全,但他不能告诉我为什么,所以我对这个问题进行了一些研究,最接近我怀疑的是: https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/809-BSI.html
http://www.iso-9899.info/wiki/Why_not_realloc
我想知道我是否可以继续在我的代码中使用realloc,或者是否有任何其他方法来重新分配内存? 谢谢你的关注。

4 个答案:

答案 0 :(得分:23)

使用realloc非常安全。这是在C程序中重新分配内存的方法。

但是,您应该始终检查错误条件的返回值。不要陷入这个共同陷阱:

p = realloc(p, new_size); // don't do this!

如果此操作失败,realloc会返回NULL,您无法访问p。而是这样做:

new_p = realloc(p, new_size);
if (new_p == NULL)
    ...handle error
p = new_p;

答案 1 :(得分:13)

这两条链接文章中的第一条提出了两项​​投诉,超出了“检查呼叫成功”这一点已经提出的要点。

  

完成此操作后,旧内容将被丢弃并留在内存中。对于清除所有数据痕迹很重要的安全内存应用程序,此行为是不合适的。

这是一个有效点,如果你碰巧存储了敏感数据(例如私钥,未散列(!)密码等),并希望使攻击更难以恢复数据或其他系统上的进程窃取数据。

  

由于它会移动内存,因此任何指向该内存的旧指针都会失效,并可能导致程序崩溃或出现异常行为。

这一点对我来说似乎是胡说八道。他们提出的解决方案并不是更好,他们malloc(),复制,然后free()具有相同净效果的原始 - 地址已经改变。如果您想要避免移动内存,那么可能能够使用某些特定于平台的调用来执行此操作,如果您安排在其附近有足够的可用地址空间。如果您知道先验要保留多少地址空间,那么您可能不会考虑首先调用realloc()

如果你在realloc()上赌博从未动过,那么总是在成长,那么无论如何你可能会有更大的问题需要担心,切换到malloc() +副本+ free()不能可能解决了这个问题。


除了“正确检查您的返回值”之外,第二篇文章中最有趣的一点是警告:

  

不要一次将缓冲区重新分配1个字节。

他们警告说:

  

这可以保证搅乱你的记忆堆

这是一个潜在有效的观点,但它不是对realloc()本身的批评;如果您使用malloc() + copy + free(),也会发生同样的情况。真正的解决方案是合理地增加缓冲区,无论你如何成长或更好,然后预先分配正确大小的块。

他们也有一点关于

  

使用realloc将内存返回给系统。

他们在这里是正确的,使用0以外的任何大小可能实际上不会返回。它可能使事情变得更糟,但这种用法似乎仍然是过早“优化”的一个例子。再次修复是使用合理大小的分配开始。

排序答案:这不是不安全的,但它也不是解决所有问题的神奇方法。

答案 2 :(得分:6)

realloc本身是安全的,但安全使用它有点棘手 - 我要说大约有85-90%的代码我看过它使用它安全地这样做。问题是realloc返回NULL表示失败 - 但是当它这样做时,你作为输入提供的指针仍然有效(前提是你没有将其分配大小调整为0)。

因此,当且仅当realloc返回非空指针时,您必须将realloc的返回值分配给您作为输入提供的指针。如果它返回空指针,则前一个指针有效,但分配没有调整大小。

另请注意,许多人认为realloc只能在放大分配时失败和/或移动分配。实际上,它可能会失败(虽然这不太可能)或将数据移动到不同的位置(更有可能),即使您减少分配大小。

答案 3 :(得分:-2)

就像C中的所有内容一样,只要你知道你做了什么,就没关系。

(知道你做了什么包括检查错误,不要使用旧指针等)