2016-12-14 9 views
1

"Expert C Programming"から練習しようとしていますが、プログラムが割り当てることができるメモリ量を知ることが重要です。これ以上割り振ることができない場合、mallocNULLを返します。NULLを返すのではなく、mallocカーネルがパニックする

#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; 
} 

私の16GB MacBook Proに合計8GBを割り当てた後、合計を印刷するのではなく、カーネルパニックが発生します。

カーネルパニックログ:私はなぜmallocを理解したい

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 

私は、これは簡単に「それはあなたがそれを行う際に、その行わない痛い?」の医師の決まり文句で固定することができることを理解するが、期待どおりに動作していません。

OSのX 10.11.5

+0

これはオペレーティングシステムの "機能"です。 –

答えて

2

その質問に明確な答えのために、あなたはここで見つけるれ、ソースコードを見ることができます。

zalloc.c source in XNU

をそのソースファイルで見つけます関数zalloc_internal()。これは、カーネルのパニックを引き起こす機能です。

この関数では、 "for(;;){"ループがあります。これは、基本的に、指定したゾーンで要求しているメモリの割り当てを試みます。十分なスペースがない場合、すぐに再度試みます。それが失敗すると、zone_gc()(ガベージコレクト)がメモリを再利用しようとします。それでも失敗した場合は、単にカーネルがパニックに陥り、効果的にコンピュータを停止させます。

zalloc.cの仕組みを理解したい場合は、ゾーンベースのメモリアロケータを参照してください。

プログラムでは、ブート時に事前定義されたゾーンである「VMマップエントリ」と呼ばれるゾーンのカーネルが空き領域を使い果たしてしまいます。一度に1 MB以上を割り当てた場合、おそらくカーネルパニックを起こすことなく、プログラムから期待している結果を得ることができます。

実際には、カーネルが数ギガバイトのメモリを割り当てても問題はありません。しかし、これらのギガバイトまで合計で何千もの小さな割り当てを割り当てることははるかに困難です。

+0

割り当てられたメモリ量を変更してもプログラムは正常に実行されませんが、カーネルパニックではありません。 – valbaca

+0

「実行に成功しました」という意味に依存します。このプログラムは実際のプログラムではありませんが、ある時点でmalloc関数が失敗するような教え方です。 – jksoegaard

+0

"実行が成功した場合:whileループ経由で割り当てることができるメモリを割り当てますN + 1番目のMBを割り当てようとすると、mallocはnullを返してwhileループを終了してprintfを終了して終了します – valbaca

関連する問題