- ベストアンサー
free()の使い方と注意点
- free()を使用して確保した領域を解放する際、注意点があります。
- struct_createで確保した領域を解放する場合、free(s);だけでは不十分です。
- 詳しく教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
この質問のデータ構造ですと、struct stackは線形リストを構成しています。 struct stack型の1つのスタックは、先頭のcellのアドレスを指定するだけで、 中身は別途cellという形で別途メモリ確保し、数珠繋ぎに繋がれます。 言い換えると、struct stackは箱で、その中に実際の中身であるstruct cellが 数珠繋ぎに入れられます。 ですので、stack_free()するときには、 ・s->headがNULLでなければ、s->head->next->next ・・・ とたどって行った 末尾のcellから順に、cellが0になるまで(s->headがNULLになるまで)メモリ解放していく ・free(s)を実施 という手順になります。 つまり、free(s)だけでは箱を開放しただけで、中身(cell)はアクセス できなくなるだけで、メモリ解放されていません。 ANo.1は残念ながら、 stack_free(s->head); で引数の型が合わず、コンパイルエラーになるはずです。
その他の回答 (1)
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
このコードの範囲だけであれば、これでOKです。 ただ、このコードの範囲だけでは、スタックとして用をなさないでしょう。 スタックですから、データをどんどんプッシュして使うはずですが、そのように、データをプッシュした状態だと、単に free(s) では、データ1個分(ここでは、struct cell 1個)のメモリが解放されるだけで、それにつながっているデータは解放されずに残ってしまいます。 この構造だと、リンクリストでスタックを実現しようとしていますから、与えられた場所以降につながっているリンクリストを順次解放する必要があります。 void stack_free(staruct stack *s) { if (s->head != NULL) { stack_free(s->head); // 与えられた場所以降に何かつながっていれば、 s->head つまり、これにつながっている部分以降を全部解放してから、 } free(s); // 先頭を解放して終わり } こんな感じで行けると思います(未確認) いずれにしても、リンクリストの取り扱いや、(この場合なら)関数の再帰的な呼び出しといった部分の理解が必要になります。