使用realloc是否安全?

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

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

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

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

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

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

如果你赌博realloc()永远不会移动,总是在增长,那么无论如何你可能会有更大的问题需要担心,切换到malloc() + copy + free()无法解决这个问题。


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

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

他们警告说:

这可以保证搅乱你的内存堆

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

他们也有一点关注

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

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

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

使用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; 

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

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

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

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

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