重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

free()の使いかたがよくわかりません。struct_createで次のように確保した領域を解放するのに、『free(s);』だけではダメだということですが、どうしてダメなのか、そしてどうしたらいいのかがわかりません。初心者なので詳しく教えていただけるとありがたいです。

#include<stdlib.h>

struct cell{
struct cell *next;
int datum;
};

struct stack{
struct cell *head;
};

struct stack *
stack_create()
{
struct stack *s;

s=malloc(sizeof(struct stack));
s->head=NULL;
return s;
}

void
stack_free(struct stack *s)
{
free(s);
}

A 回答 (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);
で引数の型が合わず、コンパイルエラーになるはずです。
    • good
    • 0

このコードの範囲だけであれば、これで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);
// 先頭を解放して終わり
}

こんな感じで行けると思います(未確認)
いずれにしても、リンクリストの取り扱いや、(この場合なら)関数の再帰的な呼び出しといった部分の理解が必要になります。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!