realloc
メモリを動的に再割り当てするために使用されます。
関数を使用して 7 バイトを割り当てた後、malloc
それを 30 バイトに拡張したいとします。
メモリに 30 バイトのシーケンシャル (1 行で連続) スペースがない場合、バックグラウンドで何が起こるでしょうか?
エラーがありますか、それともメモリが部分的に割り当てられますか?
realloc
メモリを動的に再割り当てするために使用されます。
関数を使用して 7 バイトを割り当てた後、malloc
それを 30 バイトに拡張したいとします。
メモリに 30 バイトのシーケンシャル (1 行で連続) スペースがない場合、バックグラウンドで何が起こるでしょうか?
エラーがありますか、それともメモリが部分的に割り当てられますか?
realloc
舞台裏で大まかに次のように動作します。
NULL
ます。したがって、 をテストすることで失敗をテストできNULL
ますが、古いポインターを早すぎる時期に上書きしないように注意してください。
int* p = malloc(x);
/* ... */
p = realloc(p, y); /* WRONG: Old pointer lost if realloc fails: memory leak! */
/* Correct way: */
{
int* temp = realloc(p, y);
if (NULL == temp)
{
/* Handle error; p is still valid */
}
else
{
/* p now possibly points to deallocated memory. Overwrite it with the pointer
to the new block, to start using that */
p = temp;
}
}
realloc
連続した(あなたの言葉では「順次」)メモリブロックを返すことができる場合にのみ成功します。そのようなブロックが存在しない場合は、 を返しNULL
ます。
マニュアルページから:
realloc() は、新しく割り当てられたメモリへのポインタを返します。これは、あらゆる種類の変数に対して適切に配置され、ptr とは異なる場合があり、要求が失敗した場合は NULL になります。
つまり、失敗を検出するには、結果が NULL かどうかを確認するだけです。
編集: コメントに記載されているように、呼び出しが失敗した場合、元のメモリは解放されません。
一般に、それは実装に依存します。x86(-64) Linux では、標準の doug lea malloc アルゴリズムは常に標準の x86 ページ (4096 バイト) の最小値を割り当てると信じているため、上記のシナリオでは、余分なバイトに対応するために境界をリセットするだけです。たとえば、7 バイトのバッファを PAGE_SIZE+1 に再割り当てする場合、可能であれば次の連続ページを割り当てようとするでしょう。
Linux で開発している場合は、以下を読む価値があります。
デフォルトでは、Linux は楽観的なメモリ割り当て戦略に従います。これは、malloc() が非 NULL を返す場合、メモリが実際に使用可能であるという保証がないことを意味します。これは本当に悪いバグです。システムのメモリが不足していることが判明した場合、悪名高い OOM キラーによって 1 つまたは複数のプロセスが強制終了されます。Linux がランダムに選択されたプロセスを突然失うことが望ましくない状況で使用され、さらにカーネルのバージョンが十分に新しい場合は、次のようなコマンドを使用してこのオーバーコミット動作をオフにすることができます。
# echo 2 > /proc/sys/vm/overcommit_memory
カーネル ドキュメント ディレクトリ、ファイル vm/overcommit-accounting および sysctl/vm.txt も参照してください。
FreeBSD と Mac OS X には、要求されたメモリを割り当てることができない場合に渡されたポインタを解放する reallocf() 関数があります (man realloc を参照)。