这来自《理解和使用C指针》一书
如果内存被重复分配然后丢失,则程序可能在需要更多内存时终止,但malloc无法分配内存因为内存不足。在极端情况下,操作系统可能会崩溃。以下简单示例说明了这一点:
char *chunk;
while (1) {
chunk = (char*) malloc(1000000);
printf("Allocatingn");
}
变量块从堆。但是,在另一个内存已分配给它。最终,应用程序将耗尽内存并异常终止。
所以我的问题是:我有这个样本代码:
int main(int argc, char *argv[]){
char *chunk;
while (1) {
chunk = (char*) malloc(100000000);
printf("Allocatingn");
}
}
我希望我的系统内存不足,但程序一直在运行,我看到了文本
Allocating...
一直?
当内存不足时,malloc
可能返回NULL。为此添加一个复选框。
while (1) {
printf("Allocatingn");
chunk = malloc(100000000);
if ( chunk == NULL )
{
printf("Memory allocation not successful.n");
}
else
{
printf("Memory allocation successful.n");
}
}
我想在Linux上?
仅仅因为你得到了一个指针并不意味着你实际上保留了内存。你必须亲自触摸页面才能让它成为你的。
您运行的程序没有错误。它不必异常终止。过早终止的原因是它会消耗你电脑中的所有内存,所以如果你不采取正确的措施,它就会死亡。
Linux(以及一般的unix)对系统上运行的进程施加了一些限制。在linux中,所有这些限制(请参阅ulimit(2)系统调用)默认情况下都固定为unlimited
。
当linux中的进程试图获得比系统更多的内存并分配剩余的虚拟内存时,内核会选择一个进程(最好的候选进程是试图吃掉所有内存的进程)并杀死它以恢复一些内存。这也许就是为什么你读到的文本说它异常终止的原因。你注意到这一点是因为系统试图交换你分配的所有内存,而交换程序需要所有内核的关注(所以你的系统似乎挂了一段时间——它没有,只是等待)
但您可以进行这种测试:尝试限制分配给进程的虚拟内存(使用ulimit命令,请参阅bash(1)),这样系统就可以处理消耗内存的程序。使用命令
$ ulimit -v 100000 # this allows for 100.000 kb of virtual memory
并重新运行该程序(它将能够扩展到100Mb,甚至更多)。你会看到它不会停止。它永远运行。一旦耗尽了所有可能的内存,malloc(3)就开始返回NULL
,并且该过程永远不会停止。您将看到(通过ps(1)命令)程序已分配到您施加的限制,并且不再分配,并且正在运行,消耗了100%的cpu时间。一切都在控制之中。我尝试了你的程序的以下变体:
#include <stdlib.h>
#include <stdio.h>
char *chunk;
main()
{
int i = 0;
while (malloc(1000000)) i++;
printf("run for %i times.n", i);
}
其在耗尽存储器之前对成功分配的数量进行计数并将该数字打印在CCD_ 4上。将ulimit固定为100Mb(ulimit -v 1000000
)后,此程序输出:
$ pru
run for 97 times.
(你会看到这是低于100Mb)所以,瞧!