2016-08-30 11 views
1

構造体s1の配列(ヒープ上)へのポインタp1を持ち、各構造体s1にも(ヒープ上の)別の構造体s2へのポインタがあるとします。サイズを変更するためにp1にrealloc()を呼び出すと、事前再割り当てされた配列の構造体によって保持されていた古いメモリが解放されます(ヒープ上のs2s)。realloc()は古いメモリを解放します(古いメモリが他のメモリへのポインタである場合)?

ドキュメントにはif the area pointed to was moved, a free(ptr) is doneと記載されているので、この質問に対する答えは1つのレベルまでしか解放されないことを意味します。あれは正しいですか?もしそうなら、最良の解決法は、新しい配列を手動でmallocし、古い配列を繰り返し、新しい大きな配列に値をコピーし、構造体を解放することです。

+2

'free()'は、ポインターがどのオブジェクトを指しているのかわかりません。その結果、自動的にあなたの構造体のポインタを再帰的に 'free()'することはできません。 – EOF

+0

あなたの質問は困惑のようなものです。あなたがブロック*を大きくしようとしているのであれば、おそらくより小さなブロックを除いて何も自由にする必要はありますか?あなたがブロックを小さくしようとしているのであれば、疑問があります。 –

+0

@DavidSchwartz私はサイズを変更する言葉を修正しました。私は最初に拡大を書いていました。古い要素を新しい場所にコピーしても古い要素を解放しない場合があると思ったからです。しかし、振り返ってみると、これは事実ではないと思いますか? – gowrath

答えて

1

realloc()は、与えた最上位の配列のみを再割り当てします。 EOFはコメントで言及されているように、配列の内容がポインタであることを知らないため、これらの要素には何もできません。

アレイを拡大している場合は、そのアレイが指し示すアレイで何もする必要はありません。それらのメモリは変更されず、ポインタは古いメモリからrealloc()によって割り当てられた新しいメモリにコピーされます。

配列を縮小する場合は、メモリが漏れないように、結果の終わりを超えている要素が指す配列を最初に解放する必要があります。

2

いいえ、reallocはレベル1を無料で行うことができますが、それ以上は行いません。あなたの構造体内のポインタを解放することはありません。私は配列が成長して移動できない場合、単純に同じ場所で成長するので、自由に行うことができると言った。

あなたが示唆している代替解決策は、reallocがシーンの裏で何をしているのかということです(配列を拡大することについてはまだ話していますが、他の構造体操作はそうではないと仮定しています)。あなたが正当な理由がない限り(そしてあなたは持っていないと思われます)

1

答えは間違いありません。 Reallocの動作は次のようになります。

reallocは、既存のポインタを使用するか、古いポインタを縮小または拡張できない場合は新しいポインタを割り当てます。新しいポインタが割り当てられると、新しい場所に収まるほど古いメモリの内容がコピーされます。

あなたの場合、reallocがメモリブロックを縮小すると、新しいブロックのすべてのs1ポインタは有効ですが、s1ポインタが新しいメモリブロックを超えていると、s1ポインタもs2ポインタが解放されました。メモリリークを避けるには、reallocを呼び出す前に、それらが指すメモリを解放する必要があります。

もう1つの注意点は、nullが返された場合でも古いメモリポインタは有効なので、そのコピーを保持して再利用するか、失敗したときに解放することです。

関連する問題