11

reallocメモリを動的に再割り当てするために使用されます。

関数を使用して 7 バイトを割り当てた後、mallocそれを 30 バイトに拡張したいとします。

メモリに 30 バイトのシーケンシャル (1 行で連続) スペースがない場合、バックグラウンドで何が起こるでしょうか?

エラーがありますか、それともメモリが部分的に割り当てられますか?

4

5 に答える 5

11

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;
  }
}
于 2010-09-10T11:55:50.540 に答える
6

realloc連続した(あなたの言葉では「順次」)メモリブロックを返すことができる場合にのみ成功します。そのようなブロックが存在しない場合は、 を返しNULLます。

于 2010-09-10T11:38:07.577 に答える
1

マニュアルページから:

realloc() は、新しく割り当てられたメモリへのポインタを返します。これは、あらゆる種類の変数に対して適切に配置され、ptr とは異なる場合があり、要求が失敗した場合は NULL になります。

つまり、失敗を検出するには、結果が NULL かどうかを確認するだけです。

編集: コメントに記載されているように、呼び出しが失敗した場合、元のメモリは解放されません。

于 2010-09-10T11:38:00.090 に答える
1

一般に、それは実装に依存します。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 も参照してください。

于 2010-09-10T11:54:30.870 に答える
0

FreeBSD と Mac OS X には、要求されたメモリを割り当てることができない場合に渡されたポインタを解放する reallocf() 関数があります (man realloc を参照)。

于 2010-09-10T12:04:18.917 に答える