重新分配失败的可能性有多大?
与malloc
类似,当它用完可用内存时会失败吗?或者可能还有其他原因吗?
Does it fail when it runs out of free memory similar to malloc
or could there be other reasons?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
任何分配函数(
malloc
、realloc
、calloc
以及 POSIX 上的posix_memalign
)都可能因任何原因而失败原因如下,可能还有其他原因:malloc
不会失败,但操作系统稍后会在发现时杀死一个或多个程序确实没有足够的物理内存可供使用。但在健壮的系统(包括禁用过量使用的 Linux)上,如果没有剩余物理内存,malloc
将失败。请注意,严格来说,分配函数可以在任何时间因任何原因失败。最大限度地减少失败是一个实施质量问题。即使减小对象的大小,
realloc
也可能会失败;这可能发生在严格按大小隔离分配的实现上。当然,在这种情况下,您可以简单地继续使用旧的(较大的)对象。Any of the allocation functions (
malloc
,realloc
,calloc
, and on POSIX,posix_memalign
) could fail for any of the following reasons, and possibly others:malloc
won't fail in this situation, but instead the OS will later kill one or more programs when it figures out there's not really enough physical memory to go around. But on robust systems (including Linux with overcommit disabled),malloc
will fail if there's no physical memory left.Note that strictly speaking, the allocation functions are allowed to fail at any time for any reason. Minimizing failure is a quality-of-implementation issue. It's also possible that
realloc
could fail, even when reducing the size of an object; this could happen on implementations that strictly segregate allocations by size. Of course, in this case you could simply continue to use the old (larger) object.您应该将
realloc
视为这样工作:实现可能能够比这更有效地处理特定情况,但完全按照所示方式工作的实现是 100% 正确的。这意味着
realloc(ptr, newsize)
可能会在malloc(newsize)
失败的任何时候失败;特别是,即使您缩小分配,它也可能会失败。现在,在现代桌面系统上,有充分的理由不尝试从
malloc
故障中恢复,而是将malloc
包装在函数中(通常称为xmalloc
) code>),如果malloc
失败,则立即终止程序;当然,同样的论点也适用于realloc。情况是:malloc
失败之前,用户就会厌倦他们的颠簸磁盘并强制终止您的程序。论点 1 和 2 不适用于嵌入式或移动系统(目前!),但论点 3 在那里仍然有效。
参数 3 仅适用于必须在每个调用站点检查和传播分配失败的程序。如果您很幸运能够按照预期使用 C++(即有例外),您可以依靠编译器为您创建错误恢复路径,因此测试负担会大大减轻。如今,在任何值得使用的高级语言中,您都有异常和垃圾收集器,这意味着即使您愿意,也不必担心分配失败。
You should think of
realloc
as working this way:An implementation may be able to do specific cases more efficiently than that, but an implementation that works exactly as shown is 100% correct. That means
realloc(ptr, newsize)
can fail anytimemalloc(newsize)
would have failed; in particular it can fail even if you are shrinking the allocation.Now, on modern desktop systems there is a strong case for not trying to recover from
malloc
failures, but instead wrappingmalloc
in a function (usually calledxmalloc
) that terminates the program immediately ifmalloc
fails; naturally the same argument applies torealloc
. The case is:malloc
to fail, the user will get fed up with their thrashing disk and forcibly terminate your program.malloc
failed (such shims are at best difficult, at worst impossible, to create, depending on the OS) you would have to test order of 2N failure patterns, where N is the number of calls to malloc in your program.Arguments 1 and 2 do not apply to embedded or mobile systems (yet!) but argument 3 is still valid there.
Argument 3 only applies to programs where allocation failures must be checked and propagated at every call site. If you are so lucky as to be using C++ as it is intended to be used (i.e. with exceptions) you can rely on the compiler to create the error recovery paths for you, so the testing burden is much reduced. And in any higher level language worth using nowadays you have both exceptions and a garbage collector, which means you couldn't worry about allocation failures even if you wanted to.
我想说它主要是特定于实现的。有些实施很可能会失败。有些可能会在重新分配之前使程序的其他部分失败。始终保持防御状态并检查是否失败。
请记住释放您尝试重新分配的旧指针。
总是可能存在内存泄漏。
总是这样做:
I'd say it mostly implementation specific. Some implementations may be very likely to fail. Some may have other parts of the program fail before realloc will. Always be defensive and check if it does fail.
And remember to free the old pointer that you tried to realloc.
is ALWAYS a possible memory leak.
Always do it rather like this:
你有两个问题。
在大多数现代系统上,
malloc
或realloc
失败的可能性可以忽略不计。仅当虚拟内存不足时才会发生这种情况。您的系统将在访问内存时失败,而不是在保留内存时失败。Wrt 失败
realloc
和malloc
几乎相同。realloc
可能另外失败的唯一原因是您给它一个错误的参数,即尚未使用malloc
或realloc
分配的内存或者之前已经免费
了。编辑:鉴于R.的评论。是的,您可以配置您的系统,使其在分配时失败。但首先,据我所知,这不是默认设置。它需要以这种方式配置权限,作为应用程序程序员,这不是您可以指望的。其次,即使您有一个以这种方式配置的系统,只有当您的可用交换空间被耗尽时才会出错。通常,您的机器在此之前很久就会无法使用:它将在您的硬盘上进行机械计算(又称交换)。
You have two questions.
The chances that
malloc
orrealloc
fail are negligible on most modern system. This only occurs when you run out of virtual memory. Your system will fail on accessing the memory and not on reserving it.W.r.t failure
realloc
andmalloc
are almost equal. The only reason thatrealloc
may fail additionally is that you give it a bad argument, that is memory that had not been allocated withmalloc
orrealloc
or that had previously beenfree
d.Edit: In view of R.'s comment. Yes, you may configure your system such that it will fail when you allocate. But first of all, AFAIK, this is not the default. It needs privileges to be configured in that way and as an application programmer this is nothing that you can count on. Second, even if you'd have a system that is configured in that way, this will only error out when your available swap space has been eaten up. Usually your machine will be unusable long before that: it will be doing mechanical computations on your harddisk (AKA swapping).
来自zwol的答案< /a>:
您可以看到 Git 2.29(2020 年第 4 季度)应用了该原则:
xrealloc()
可以发送已释放的非 NULL 指针,这一点已得到修复。请参阅 提交 6479ea4(2020 年 9 月 2 日),作者:杰夫·金 (
peff
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 56b891e,2020 年 9 月 3 日)From zwol's answer:
You can see that principle applied with Git 2.29 (Q4 2020): It was possible for
xrealloc()
to send a non-NULL pointer that has been freed, which has been fixed.See commit 6479ea4 (02 Sep 2020) by Jeff King (
peff
).(Merged by Junio C Hamano --
gitster
-- in commit 56b891e, 03 Sep 2020)