malloc返回值为条件

时间:2021-09-14 18:54:59

In a bunch of programs I came across regarding dynamic memory allocation I always find the same piace of code when it was need to allocate dynamic memory:

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

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

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

// else the program keep running

I was wondering why it's not used, or at least I've never seen it, something like that:

我想知道为什么它没有被使用,或者至少我从未见过它,类似的东西:

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

I though about it and the only thing I came up with is that if you can't allocate new memory is because there is no more left on the heap so the 2nd example would turn into an infinite-loop. Is that right? Because if the memory allocation fails for some other reasons (I don't really know which) than putting the allocation inside a loop would probably solve the problem.

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

Am I missing something? Which one of the "style" is preferred?

我错过了什么吗?哪种“风格”更受青睐?

4 个解决方案

#1


1  

The only use case I can imagine for re-trying a failed malloc, would be a program running in a environment supporting bursts of memory allocation from different programs, all fully releasing it soon. In that case, a program unable to acquire all the necessary memory should just wait until another one releases enough to proceed.

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

But that would require the programmer to be very cautious as there is an immediate corner case. Suppose the system has 4 GB of free memory, that is when none of the memory consuming processes are running. Suppose that one could get 1.5GB, and needs 1.5 more, while another one also has 1.5 GB and also needs 1.5 more. You are in a nice and clean deadlock, because only 1 GB is available and both processes are waiting for the other to release anything.

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

Even if a process that cannot acquire all the necessary memory had to release everything before entering a loop, you could fall in race conditions where processes only acquire part of what they need, fail to get all, release and loop again if no process if able to acquire all at once.

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

As we prefer robust systems, programs assume that memory will be available, and just abort if it is not. It is now the problem of a human being to choose whether it is better to add memory, change the program to let it use less memory, or serialize processing to have only one big program at the same time or...

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

#2


1  

As per the malloc man page, malloc can fail with only one error, which is ENOMEM, which is the out of memory error. There is no point of retrying in this case.

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

The style of retrying in a while loop is usually followed with other system calls, such as read(2), open(2), select(2), etc. which can return -1 to indicate an error and set the errno to EINTR, which means that they were interrupted because of a signal. You would usually want to retry the call again in this case.

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

#3


0  

If there is no memory left, it would indeed cause your program to hang up in an infinite busy-loop, occupying CPU.

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

If your computer is running out of memory, I think the last thing you need is some ghost process remaining in RAM, stealing CPU.

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

It is better that your program gracefully terminates and inform the user that they are out of memory. Because running out of memory is a rather severe error condition on most computers.

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

This could in turn be caused by memory leaks, heap corruptions and other nasty things that make the execution environment for your program unstable. Which probably means that bugs in your own process are to blame. Which in turn means that the process won't recover from the error state by itself.

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

#4


0  

Memory allocations are not retried when they fail because there is no reason to expect that after once failing, they will succeed on any subsequent attempt without anything having changed. That certainly applies to the insufficient memory case, as you observed, but it also applies to any other plausible failure mode you can imagine. After all, if malloc() could recover on its own, then it would not need to fail in the first place.

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

Thus, a tight memory-allocation loop such as you propose is about as bad as not testing whether the allocation succeeds at all. In the failure case, it is highly likely to put the program into an infinite loop, no matter what the reason for the failure.

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

#1


1  

The only use case I can imagine for re-trying a failed malloc, would be a program running in a environment supporting bursts of memory allocation from different programs, all fully releasing it soon. In that case, a program unable to acquire all the necessary memory should just wait until another one releases enough to proceed.

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

But that would require the programmer to be very cautious as there is an immediate corner case. Suppose the system has 4 GB of free memory, that is when none of the memory consuming processes are running. Suppose that one could get 1.5GB, and needs 1.5 more, while another one also has 1.5 GB and also needs 1.5 more. You are in a nice and clean deadlock, because only 1 GB is available and both processes are waiting for the other to release anything.

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

Even if a process that cannot acquire all the necessary memory had to release everything before entering a loop, you could fall in race conditions where processes only acquire part of what they need, fail to get all, release and loop again if no process if able to acquire all at once.

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

As we prefer robust systems, programs assume that memory will be available, and just abort if it is not. It is now the problem of a human being to choose whether it is better to add memory, change the program to let it use less memory, or serialize processing to have only one big program at the same time or...

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

#2


1  

As per the malloc man page, malloc can fail with only one error, which is ENOMEM, which is the out of memory error. There is no point of retrying in this case.

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

The style of retrying in a while loop is usually followed with other system calls, such as read(2), open(2), select(2), etc. which can return -1 to indicate an error and set the errno to EINTR, which means that they were interrupted because of a signal. You would usually want to retry the call again in this case.

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

#3


0  

If there is no memory left, it would indeed cause your program to hang up in an infinite busy-loop, occupying CPU.

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

If your computer is running out of memory, I think the last thing you need is some ghost process remaining in RAM, stealing CPU.

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

It is better that your program gracefully terminates and inform the user that they are out of memory. Because running out of memory is a rather severe error condition on most computers.

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

This could in turn be caused by memory leaks, heap corruptions and other nasty things that make the execution environment for your program unstable. Which probably means that bugs in your own process are to blame. Which in turn means that the process won't recover from the error state by itself.

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

#4


0  

Memory allocations are not retried when they fail because there is no reason to expect that after once failing, they will succeed on any subsequent attempt without anything having changed. That certainly applies to the insufficient memory case, as you observed, but it also applies to any other plausible failure mode you can imagine. After all, if malloc() could recover on its own, then it would not need to fail in the first place.

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

Thus, a tight memory-allocation loop such as you propose is about as bad as not testing whether the allocation succeeds at all. In the failure case, it is highly likely to put the program into an infinite loop, no matter what the reason for the failure.

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