Memory malloc内核恐慌而不是返回NULL

Memory malloc内核恐慌而不是返回NULL,memory,Memory,我试图做一个练习,重点是看看一个程序能分配多少内存。当无法再分配时,它依赖于返回NULL #include <stdio.h> #include <stdlib.h> int main() { int totalMB = 0; int oneMeg = 1<<20; while (malloc(oneMeg)) { ++totalMB; } printf("Allocated %d Mb total \

我试图做一个练习,重点是看看一个程序能分配多少内存。当无法再分配时,它依赖于返回
NULL

#include <stdio.h>
#include <stdlib.h>

int main() {
    int totalMB = 0;
    int oneMeg = 1<<20;
    while (malloc(oneMeg)) {
        ++totalMB;
    }
    printf("Allocated %d Mb total \n", totalMB);
    return 0;
}
我明白医生的陈词滥调“你那样做会痛吗?那就不要那样做”很容易就能解决这个问题,但我想了解为什么
malloc
不能按预期工作


OS X 10.11.5

要获得该问题的最终答案,您可以查看源代码,您可以在这里找到:

在该源文件中找到函数zalloc_internal()。这是导致内核死机的函数

在函数中,您将找到一个“for(;){”循环,它基本上是尝试在指定区域中分配您正在请求的内存。如果没有足够的空间,它将立即重试。如果失败,它将执行区域_gc()(垃圾收集)试图回收内存。如果这也失败了,它只是内核恐慌——有效地停止了计算机

如果您想了解zalloc.c的工作原理,请查找基于区域的内存分配器

您的程序正在使内核在名为“VM映射条目”的区域中耗尽空间,该区域是在启动时分配的预定义区域。如果一次分配的内存超过1 MB,您可能会从程序中获得预期的结果,而不会出现内核死机


从本质上讲,内核分配几GB的内存并不是什么问题。但是,分配数千个较小的分配(总计为这些GB)要困难得多。

查找“延迟分配”,这是一个“功能”更改分配的内存量不会导致程序成功运行,但不会导致内核死机。这取决于“成功运行”的含义。该程序不是一个真正的程序,而是一个教学示例,其中malloc函数注定会在某个点失败。"成功运行意味着:通过while循环分配尽可能多的内存。当malloc尝试分配N+1thMB时,malloc应该返回null,退出while循环,然后它应该printf并退出。如果不再看到内核死机,您需要在问题中指定发生了什么而不是预期的结果。请记住r您的示例可能有点过时—当前的操作系统将竭尽全力满足您的malloc()请求,包括将RAM交换到磁盘、压缩内存、执行延迟分配等。
Anonymous UUID:       0B87CC9D-2495-4639-EA18-6F1F8696029F

Tue Dec 13 23:09:12 2016

*** Panic Report ***
panic(cpu 0 caller 0xffffff800c51f5a4): "zalloc: zone map exhausted while allocating from zone VM map entries, likely due to memory leak in zone VM map entries (6178859600 total bytes, 77235745 elements allocated)"@/Library/Caches/com.apple.xbs/Sources/xnu/xnu-3248.50.21/osfmk/kern/zalloc.c:2628
Backtrace (CPU 0), Frame : Return Address
0xffffff91f89bb960 : 0xffffff800c4dab12 
0xffffff91f89bb9e0 : 0xffffff800c51f5a4 
0xffffff91f89bbb10 : 0xffffff800c5614e0 
0xffffff91f89bbb30 : 0xffffff800c5550e2 
0xffffff91f89bbba0 : 0xffffff800c554960 
0xffffff91f89bbd90 : 0xffffff800c55f493 
0xffffff91f89bbea0 : 0xffffff800c4d17cb 
0xffffff91f89bbf10 : 0xffffff800c5b8dca 
0xffffff91f89bbfb0 : 0xffffff800c5ecc86 

BSD process name corresponding to current thread: a.out

Mac OS version:
15F34