使用 realloc 是不是安全?
Posted
技术标签:
【中文标题】使用 realloc 是不是安全?【英文标题】:Is it safe to use realloc?使用 realloc 是否安全? 【发布时间】:2012-02-22 16:49:54 【问题描述】:前段时间,我的一个朋友告诉我不要使用realloc
,因为它不安全,但他无法告诉我原因,所以我对该主题进行了一些研究,最接近我怀疑的参考是:
-
First
Second
我想知道我是否可以继续在我的代码中使用realloc
,或者它是否不安全,是否有任何其他方法可以重新分配内存?
【问题讨论】:
你知道Linux不保留内存吗?malloc
和 realloc
永不失败。相反,如果您的内存不足,您的程序将会崩溃。
【参考方案1】:
使用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;
【讨论】:
这取决于您的 C 库。realloc
的一些实现只需执行 malloc
、memcpy
、free
。这使得 realloc 不是很有用......【参考方案2】:
两篇链接文章中的第一篇提出了两个投诉,超出了此处已经提出的“检查调用成功”点。
完成后,旧内容将被丢弃并留在内存中的某个位置。对于擦除所有数据痕迹很重要的安全内存应用程序,这种行为是不合适的。
这是一个有效的点如果您碰巧存储了敏感数据(例如私钥、未散列的(!)密码等)并希望让漏洞更难恢复数据或其他系统上的进程窃取数据。
由于它会移动内存,任何指向该内存的旧指针都会变得无效,并可能导致程序崩溃或其他行为异常。
这点对我来说似乎是无稽之谈。他们提出的解决方案也好不到哪里去,他们malloc()
,复制然后free()
具有相同净效果的原件 - 地址已更改。如果您想避免移动内存,可能可以使用一些特定于平台的调用来执行此操作,前提是您安排在它们附近有足够的可用地址空间。如果您先验知道要保留多少地址空间,那么您可能一开始就不会考虑调用realloc()
!
如果您在赌 realloc()
永不移动,一直在增长,那么您可能有更大的问题需要担心,而切换到 malloc()
+ 复制 + free()
不可能解决这个问题。
除了“正确检查你的返回值点”之外,第二篇文章中最有趣的一点是警告:
不要一次重新分配 1 个字节的缓冲区。
他们警告:
这保证会搅动你的内存堆
这是一个潜在的有效观点,但它并不是对realloc()
本身的批评;如果您使用malloc()
+copy+free()
,也会发生同样的情况。真正的解决方法是明智地增加缓冲区,无论您如何增加它们,或者更好地预先分配正确大小的块。
他们也有观点
使用 realloc 将内存返回给系统。
他们在这里是正确的,因为使用 0 以外的任何大小实际上可能不会返回。它可能不会让事情变得更糟,但这种用法似乎仍然是过早“优化”的一个例子。再次修复是使用合理大小的分配开始。
排序答案:它不是不安全的,但也不是解决所有问题的神奇方法。
【讨论】:
【参考方案3】:realloc
本身是安全的,但安全地使用它有点棘手——我会说我见过的大约 85-90% 的代码使用它不 安全地这样做。问题是realloc
返回 NULL 以指示失败 - 但是当它这样做时,您作为输入提供的指针仍然有效(前提是您没有将其分配大小调整为 0)。
因此,当且仅当 realloc
返回一个非空指针时,您必须将来自 realloc
的返回分配给您作为输入提供的指针。如果它返回一个空指针,你之前的指针是有效的,但是分配没有被调整大小。
另请注意,许多人认为realloc
只能在您放大分配时失败和/或移动分配。实际上,即使您减少分配大小,它也可能会失败(尽管这不太可能)或将数据移动到不同的位置(更有可能)。
【讨论】:
【参考方案4】:就像 C 中的所有东西一样,只要你知道你在做什么,就可以了。
(知道你在做什么包括检查错误,不要使用旧指针等)
【讨论】:
我认为问题是“我需要做什么?”,所以这并没有真正回答它 好吧,他说I want to know if I can continue to use realloc
。答案是肯定的。
当我发布该评论时,您只有答案的第一句话
我反对“像 C 中的一切”。 C 中的一件事,gets
,永远都不好。当然严格来说 C11 现在是“C”,所以 gets
不再是“C 中的”。 :-)以上是关于使用 realloc 是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
使用 realloc() 使 memmove() 安全 [重复]
为啥使用 std::vector 而不是 realloc? [关闭]
找出分配的内存是不是被 C 中的 realloc() 函数释放