2011-11-12 11 views
2

私のコードについての短い質問があります。私は、テストのための2つの状況または例を作成しました。Cメモリフリーの混乱

例1:

char *arr[1000000]; 
int i = 0; 
for (; i < 1000000; i++){ 
    char *c = (char *) calloc(1, sizeof(char) * 10); 
    free(c); 
} 

例2:実施例における

char *arr[1000000]; 
int i = 0; 
for (; i < 1000000; i++){ 
    char *c = (char *) calloc(1, sizeof(char) * 10); 
    arr[i] = c; 
    free(arr[i]); 
    arr[i] = NULL; 
} 

貴様:メモリをfree'ing前に、アレイに置きます。

例1を実行すると、すべてのメモリが解放されます。例2を実行すると、すべてのメモリが解放されるわけではありません。 私は検索して見ましたが、理解できませんでした。

例2の結果が例1と異なるのはなぜですか。

私の常識は、例1と2は同じ結果になるはずですが、実際にはそうではありません。私はメモリの使用状況を調べるためにlinux topを使用します。

+6

と同じになりますすべての記憶を解放しますか? – EricSchaefer

+0

2番目の例はすべてのメモリを解放していないと推測していますか? – Joe

+0

あなたは何を確認しましたか?プロセスのRSS? – wildplasser

答えて

3

デマンドページングによって発生します。プロセスには配列のアドレス空間があります(つまり、ページテーブルエントリが存在しますが)(まだ)メモリが接続されていません。ループは配列[]に属するすべてのメモリページを(最終的に)割り当てるため、ループの最後にはすべてのページが「フォールトイン」されています。

コンセプトの証明として、あなたがループを置き換えることができます。

for (; i < 1000000; i++){ 
    arr[i] = "hello, world!"; 
} 

そして、結果はおそらく、(ほぼ)あなたはそれがない知ってどのようにスニペット#2

4

結果は同じです。なぜ違いがあると思うのか分かりません。

+0

私のメモリ使用量が異なる値を示しています –

+0

@Timどのようにメモリ使用量をチェックしますか? –

+0

@etienne:linux先頭へ –

3

どちらも同じです。

メモリを読み取るのにtopを使用しているので、その違いはコンパイラの最適化で説明できます。たとえば、例1の配列を完全に最適化することができます。

メモリの問題を確認するには、valgrindなどのツールを使用する必要があります。