36

C の realloc 関数に関する簡単な質問: realloc を使用してポインターが指しているメモリ ブロックを縮小すると、「余分な」メモリは解放されますか? それとも、何らかの方法で手動で解放する必要がありますか?

たとえば、

int *myPointer = malloc(100*sizeof(int));
myPointer = realloc(myPointer,50*sizeof(int));
free(myPointer);

メモリリークは発生しますか?

4

5 に答える 5

28

いいえ、メモリ リークは発生しません。realloc将来のmalloc操作のために残りを「使用可能」とマークするだけです。

ただし、free myPointer後で行う必要があります。余談ですが0、 のサイズとして使用すると、一部の実装reallocと同じ効果があります。Steve Jessop と R.. がコメントで述べたように、それに頼るべきではありません。free

于 2011-08-16T12:13:00.267 に答える
21

realloc確かにメモリリークはありませんが、サイズを小さくするために呼び出すと、少なくとも3つのいずれかが発生する可能性があります。

  1. 実装は、割り当てられたメモリブロックを新しい要求された長さで分割し、最後に未使用部分を解放します。
  2. 実装は、新しいサイズで新しい割り当てを行い、古いコンテンツを新しい場所にコピーし、古い割り当て全体を解放します。
  3. 実装は何もしません。

オプション3はかなり悪い実装ですが、完全に合法です。後で呼び出すとすべてが解放されるため、「メモリリーク」はまだありませんfree

オプション1と2に関しては、パフォーマンスを優先するか、メモリの断片化を回避するかによって、どちらが適切かが大きく異なります。ほとんどの実際の実装は、オプション1を実行することに傾いていると思います。

于 2011-08-16T12:31:02.177 に答える
6

再割り当てが失敗した場合でも、新しいコードは元の割り当てをリークします。ほとんどの実装でブロックの縮小に失敗することはないと思いますが、許可されています。ブロックを拡大するか縮小するかに関係なく、realloc を呼び出す正しい方法は void *tmp = realloc(myPointer, 50*sizeof(int)); です。if (!tmp) { /* エラーを何らかの方法で処理します。myPointer はまだ割り当てられている古いブロックを指しています */ } myPointer = tmp;. – スティーブ・ジェソップ 48分前

こんにちは、コメントへの返信方法がわかりませんでした、申し訳ありません。

tmp を myPointer の型にキャストする必要がありますか? この場合、私は書く必要がありますか?

myPointer = (int*)tmp

あと、この場合 free(myPointer) すると tmp の指すメモリも解放されますよね?だからやる必要ない

free(myPointer)
free(tmp)
于 2011-08-16T13:36:50.737 に答える
4

あなたがコードを与えた方法では、はい、リークがある可能性があります。のアイデアはrealloc、データの新しい場所を返すことができるということです。あなたがあなたの質問でそれをするように、あなたはあなたをrealloc送るそのポインタを失います。

int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2); 
myPointer = myPointer2;
于 2011-08-16T12:37:26.420 に答える