realloc
ポインタ変数に再度使用する前にメモリを解放する必要がありますか。次のうち正しいのはどれ?
for(i = 0; i < n; i++){
myArray = (int *)realloc(myArray, i*sizeof(int));
}
for(i = 0; i < n; i++){
myArray = (int *)realloc(myArray, i*sizeof(int));
free(myArray);
myArray = NULL;
}
realloc
ポインタ変数に再度使用する前にメモリを解放する必要がありますか。次のうち正しいのはどれ?
for(i = 0; i < n; i++){
myArray = (int *)realloc(myArray, i*sizeof(int));
}
for(i = 0; i < n; i++){
myArray = (int *)realloc(myArray, i*sizeof(int));
free(myArray);
myArray = NULL;
}
の具体的な有用性realloc
は、それを使用する前に必要がないfree
ことです。すでに割り当てられているメモリを増やすために存在します。
したがって、これは必須ではなく、一般的ではありません。NULL
ポインターを渡すと、 のようにrealloc
動作しmalloc
ます。呼び出す前に使用している場合はfree
、使用している可能性がありますmalloc
。
エラー処理を省略したため、どちらの例も正しくありません。すべてのアロケーターが戻る可能性があり、この点NULL
での使用realloc
は少し注意が必要です。ドキュメントと例を注意深く読んでください。具体的には、 ifが失敗して を返す場合、参照が失われ、メモリがリークしているだけptr = realloc(ptr, ...
なので、常に悪い考えです。代わりに tmp 変数を使用してください。realloc
NULL
tmp = realloc(ptr, newSize);
if (tmp != NULL)
ptr = tmp;
else handle_error();
どちらでもない。NULL を返す realloc を常にチェックする必要があります。そうしないと、メモリリークが発生します。また、アロケーター関数の戻り値をキャストしていますが、これはお勧めできません。また、後で配列/ポインターの型を変更し、ここでも型を変更するのを忘れた場合、追跡が困難な segfault に直面することになるためsizeof(*myArray)
、明示的な構造の代わりに使用することをお勧めします。 sizeof(type)
/またはメモリ リーク エラー。総括する:
for(i = 0; i < n; i++){
int *tmp;
tmp = realloc(myArray, i*sizeof(*myArray));
if (tmp == NULL)
{
free(myArray);
/* And handle error */
}
myArray = tmp;
}
さて、あなたの質問に実際に答えるには、free() を使う必要はありません。
これは、何をしたいかによって異なります。 realloc()
具体的には、既存の割り当てを取得してそのサイズを変更し、できるだけ多くのデータを保持するように設計されています。あなたが提供した両方の例は、コンパイルされるという意味では正しいですが、異なることを行います。
realloc(NULL, n)
は と同じなmalloc(n)
ので、2 番目のケースは次と意味的に同等です。
for(i = 0; i < n; i++){
myArray = (int *)malloc(i*sizeof(int));
free(myArray);
myArray = NULL;
}
最初の例では、 が指すデータmyArray
が保持されます。2 番目の例では、既存の割り当てが破棄され、初期化されていない新しい割り当てに置き換えられます。元の割り当てが指すデータはすべて破棄されます。
は、割り当てが失敗した場合realloc()
に返されることに注意してください。ただし、ポインタ以外を渡した場合、その割り当ては解放されません。1 つのポインターを渡してその同じポインター変数に直接結果を代入すると、元の割り当てがまだ存在するため、再割り当てが失敗した場合にメモリ リークが発生する可能性があります。これを行う正しい方法は、一時ポインター変数を使用することです。NULL
NULL
realloc()
いいえ、なぜですか?要点はrealloc
、既存のメモリ ブロックを再割り当てし、そのメモリ ブロックに既に格納されている値を保持することです。アイデアは、場合によっては、完全に新しいメモリ ブロックを割り当てて古い値をそこにコピーする代わりに、既存のメモリ ロケーションを再利用する可能性があるということです。
古いブロックの内容を保存したくない場合は、まったく必要ないかもしれませんrealloc
。
また、適切な引数値が与えられた場合、 の機能はおよびrealloc
の機能もカバーすることに注意してください。コードの 2 番目のサイクルで行っていることは、基本的に純粋モードで使用しています。malloc
free
realloc
malloc