这来自本书:Understanding and Using C Pointers
如果重复分配然后丢失内存,则程序 当需要更多内存但malloc无法分配时可能会终止 因为它耗尽内存。在极端情况下,操作系统 可能会崩溃。这在以下简单示例中说明:
char *chunk;
while (1) {
chunk = (char*) malloc(1000000);
printf("Allocating\n");
}
变量块从中分配内存 堆。但是,此内存不会在另一个块之前释放 内存被分配给它。最终,应用程序将耗尽 记忆并异常终止。
所以我的问题: 我有这个示例代码:
int main(int argc, char *argv[]){
char *chunk;
while (1) {
chunk = (char*) malloc(100000000);
printf("Allocating\n");
}
}
好吧我期待我的系统内存耗尽,但程序一直在运行,我看到了文本
Allocating...
一直在吗?
答案 0 :(得分:6)
如果没有足够的内存malloc
可能会返回NULL。添加一张支票。
while (1) {
printf("Allocating\n");
chunk = malloc(100000000);
if ( chunk == NULL )
{
printf("Memory allocation not successful.\n");
}
else
{
printf("Memory allocation successful.\n");
}
}
答案 1 :(得分:2)
在Linux上我假设?
仅仅因为你找回指针并不意味着你实际上保留了那个记忆。您必须亲自触摸该页面才能成为您的页面。
答案 2 :(得分:1)
您运行的程序不正确。它不必异常终止。提前终止的原因是它消耗了计算机中的所有内存,所以如果你没有采取正确的措施,它就会死掉。
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);
}
计算内存耗尽前的成功分配数,并在stdout
上打印该数字。将ulimit修复为100Mb(ulimit -v 1000000
)后,该程序输出:
$ pru
run for 97 times.
(你会看到它低于100Mb)所以,瞧!