web-dev-qa-db-ja.com

reallocは古いコンテンツを上書きしますか?

realloc()を使用してメモリを再割り当てすると、以前の内容は上書きされますか?データを入力するたびにメモリを再割り当てするプログラムを作成しようとしています。

Reallocによるメモリ割り当てについて教えてください、たとえばコンパイラに依存していますか?

36
fuddin

古い内容を気にする必要はありません。

reallocを使用する正しい方法は、再割り当てに特定のポインターを使用し、そのポインターをテストして、問題がなければ、古いポインターを変更することです。

int *oldpointer = malloc(100);

/* ... */

int *newpointer = realloc(oldpointer, 1000);
if (newpointer == NULL) {
    /* problems!!!!                                 */
    /* tell the user to stop playing Doom and retry */
    /* or free(oldpointer) and abort, or whatever   */
} else {
    /* everything ok                                                                 */
    /* `newpointer` now points to a new memory block with the contents of oldpointer */
    /* `oldpointer` points to an invalid address                                     */
    oldpointer = newpointer;
    /* oldpointer points to the correct address                                */
    /* the contents at oldpointer have been copied while realloc did its thing */
    /* if the new size is smaller than the old size, some data was lost        */
}

/* ... */

/* don't forget to `free(oldpointer);` at some time */
85
pmg

既存のコンテンツを上書きせずに既に割り当てられているメモリを拡張するか、または(拡張できない場合)別の場所に新しい大きなメモリを割り当て、既存のコンテンツを以前のメモリから新しいメモリにコピーします。

12
ChrisW

古いポインタが上書きされたかのようにプログラムする必要があります。古いメモリは割り当てられなくなったので、プログラムの別の部分(またはシステムスレッドなど)によって再割り当てされ、reallocを呼び出した後はいつでも上書きできます。

ただし、新しいメモリには常に古いメモリに存在していたのと同じデータが常に含まれますが(必要に応じてコピーされます)、古いブロックのサイズまでは、最後に割り当てられた余分なスペースは初期化されません。

コピーが必要な場合は、新しいmallocを実行してmemcpyを使用してください。

実装に関しては、reallocを呼び出してincreaseサイズを呼び出すと、次のいずれかが発生する可能性があります。

  • 新しいブロックが割り当てられ、古いメモリの内容がコピーされ、古いブロックが解放され、新しいポインタが返されます。
  • ブロックの後の領域が割り当てられていない場合、既存のブロックが拡張され、同じポインタが返されることがあります。

何が起こったのかを知る方法がないため、または上記の提案とはまったく異なる実装が使用されている場合でも、常にreallocの仕様に従ってコーディングする必要があります。つまり、これ以上古いポインターを使用してはいけません。新しいものを使用する必要があります。

9
jhabbott

何を質問しているのかを伝えるのは難しいですが、reallocに渡された古いアドレスの「古い内容」を読み取れるかどうかを質問している場合、答えはnoです。場合によっては、そこに古いコンテンツの一部またはすべてが見つかることがありますが、reallocが渡したものと同じポインターを返さない限り、古いポインターの使用は未定義です動作

reallocから返された新しいアドレスに古いコンテンツを保持するかどうかを単に質問している場合、答えは「はい」です(古いサイズと新しいサイズの最小値まで)。