malloc返回值为条件

时间:2016-12-01 15:17:07

标签: c memory memory-management

在我遇到的关于动态内存分配的一系列程序中,当需要分配动态内存时,我总能找到相同的代码:

int *pointer = (int *)malloc(sizeof(int));

if(pointer == NULL)
    exit(1); // or return 1

// else the program keep running

我想知道为什么没有使用它,或者至少我从未见过它,就像那样:

int *pointer
while((pointer = (int *)malloc(sizeof(int)) == NULL);

我虽然关于它,但我唯一想到的是,如果你不能分配新的内存是因为堆上没有剩下的东西,所以第二个例子会变成无限 - 环即可。是对的吗?因为如果内存分配由于某些其他原因(我真的不知道哪个)而失败,那么将分配放在循环中可能会解决问题。

我错过了什么吗?其中一个" style"是首选?

5 个答案:

答案 0 :(得分:1)

根据malloc手册页,malloc可能会失败,只有一个错误,即ENOMEM,这是内存不足错误。在这种情况下没有重试的重点。

while循环中重试的样式通常会跟随其他系统调用,例如read(2)open(2)select(2)等,它们可以返回-1以指示错误并将errno设置为EINTR,这意味着它们因信号而中断。在这种情况下,您通常希望再次重试该呼叫。

答案 1 :(得分:1)

我可以想象的唯一用于重新尝试失败的malloc的用例,将是一个在不同程序中支持突发内存分配的环境中运行的程序,所有这些都将很快完全释放 。在这种情况下,无法获取所有必要内存的程序应该等到另一个程序释放到足以继续进行。

但这需要程序员非常谨慎,因为有一个直接的角落案例。假设系统具有4 GB的 free 内存,即没有任何内存使用进程正在运行。假设一个可以获得1.5GB,需要1.5个,而另一个也需要1.5 GB,还需要1.5个。你处于一个漂亮而干净的死锁中,因为只有1 GB可用,并且两个进程都在等待另一个进程释放任何内容。

即使一个无法获取所有必要内存的进程必须在进入循环之前释放所有内容,你也可能陷入竞争条件,其中进程只获取他们需要的部分内容,无法获得所有内容,如果没有,则再次释放和循环过程如果能够一次获得所有。

由于我们更喜欢健壮的系统,程序会假设内存可用,如果不是,则中止。现在是人类选择是否更好地添加内存,更改程序以使其使用更少的内存,或序列化处理以同时只有一个大程序或... ...

答案 2 :(得分:0)

如果没有剩余内存,它确实会导致程序在无限繁忙循环中挂起,占用CPU。

如果您的计算机内存不足,我认为您需要的最后一件事就是内存中存在一些虚假进程,窃取CPU。

最好是程序正常终止并通知用户内存不足。因为在大多数计算机上内存不足是一个相当严重的错误情况。

这可能反过来是由内存泄漏,堆损坏和其他令人讨厌的事情导致程序的执行环境不稳定造成的。这可能意味着你自己的过程中的错误应该受到责备。这反过来意味着该过程本身不会从错误状态中恢复。

答案 3 :(得分:0)

内存分配在失败时不会重试,因为没有理由认为一旦失败,它们将在任何后续尝试中成功,而不会发生任何变化。这肯定适用于内存不足的情况,正如您所观察到的那样,但它也适用于您可以想象的任何其他合理的故障模式。毕竟,如果malloc()可以自行恢复,那么首先不需要失败。

因此,像你提出的严格的内存分配循环和不测试分配是否成功一样糟糕。在失败的情况下,无论失败的原因是什么,都很可能将程序置于无限循环中。

答案 4 :(得分:0)

至少在Windows计算机上,在循环中重试malloc实际上是有意义的(但在无限循环中则没有意义)。在这里查看我的详细答案: https://stackoverflow.com/a/30495537/2986286

将页面文件设置为自动增长时,当页面文件大小必须增长时,内存分配可能会失败。重试分配有助于解决此问题。