質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.81%

C言語:freeの方法に関して

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 220

score 8

作成したプログラムの抜粋

// 単方向リスト
typedef struct list{
  char list_name[256];
  struct list *next; // 次のノードのアドレス
} LIST;
LIST *list_head = NULL;
LIST *list_tail = NULL;

int main()
{
  LIST *p, *q;

  (適当な処理により単方向リストを生成)

  /* メモリの解放 */
  p = list_head;
  while(p != NULL){
    q = p->next;
    free(p);
    p = q;
  }

  return 0;
}

質問

このメモリの解放は正しくできているでしょうか?
出来ていない場合は誤りを指摘いただければ幸いです。

補足

みなさま、たくさんのご回答ありがとうございます。
以下により、メモリを動的に確保しています。
質問の意図は、正しく単方向リストが作られたものとして、それをプログラムの終わり際にすべてメモリ解放して、メモリリークを防ぎたいというものです。
したがって、単方向リストすべてがfreeされていますか、という質問です。

LIST *newNode;
newNode = (LIST *)malloc(sizeof(LIST));

(その他、単方向リストを正しく作成する処理)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fana

    2021/07/22 11:19

    > (適当な処理により単方向リストを生成)

    の部分は,まぁ,「示さずとも想像がつくだろ」って話なのでしょうが,
    「解放処理が正しいか?」と言われれば,それを作った箇所が「本当に想像通りか」次第となるわけですから,
    そこも省略せずに示すべきではないかと.

    キャンセル

  • Zuishin

    2021/07/23 11:12 編集

    > それをプログラムの終わり際にすべてメモリ解放して、メモリリークを防ぎたいというものです。

    プログラムの終わりに限った話なら解放する必要はありません。
    メモリリークも起きません。

    > newNode = (LIST *)malloc(sizeof(LIST));

    これがどこでどのように何度呼ばれているかで正しく解放されているかどうかも変わります。

    キャンセル

  • SUNMOON_14

    2021/07/23 11:19

    私の場合は、プログラムの終わりでもfreeしなければならないという制約があります。

    キャンセル

  • Zuishin

    2021/07/23 11:21

    なんだ、そういえば課題か。

    キャンセル

回答 3

+2

このメモリの解放は正しくできているでしょうか?

ご自身で確認してみてはどうでしょうか.

freeを使うということは,それよりも前にmallocとかを用いてるハズで,

正しく開放できているか? という話は,
mallocしたらそこを確実に(1回だけ)freeしなきゃならない」というのをちゃんとできているか?という話になるでしょうから,

例えば,

  • mallocを使う度に,その戻り値をprintfなりで表示する
  • freeを使う度に,そこに渡した値をprintfなりで表示する

ということをしてみて,
「前者側で表示された全ての値が,後者側で一度だけ現れるのか?」ということをチェックしてみればよいでしょう.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/07/22 11:32

    「解放」処理の後に,まだ何かをするのであれば

    > list_head

    みたいなやつの値はちゃんとNULLにしとかないと,以降で事故るかもしれない.

    キャンセル

checkベストアンサー

0

全体をfreeするという意味ならこれで良いと思います(動作未検証)

ただ、リスト構造の醍醐味の一つは、全体に影響を与えず任意の部分を修正できる点にあります。

例えば、ルーズリーフの中途ページだけを引き抜いたりできるような機能です。全体削除のみだけならリストの利点を利用しておりません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/07/22 14:42 編集

    リストにクリア機能は必須とまでは言いませんが、まずまず使用頻度が高いかと。

    というより、リストを繰り返し作成・解放するような使い方もあり、その場合はクリアしなければメモリリークします。

    キャンセル

  • 2021/07/22 15:13

    クリア機能という意味ならOKですが、出題の意図を要確認という意味です。

    キャンセル

  • 2021/07/22 15:35

    どうやってメモリを割り当てているかが書かれていないため質問としては不十分ですが、意図のみ言えば不明瞭なものがあるようには思えません。
    クリアの仕方はこれで正しいかという問いでしょう。

    キャンセル

  • 2021/07/22 15:44

    クリアの仕方という意味ならOKです。

    キャンセル

0

厳密な検証してませんが、、、

    q = p->next;
   free(p);
   p = q;

free(p)したところで、pの中身の参照/変更は不可。(まあ、参照なら、大抵できるが) しかし、その後で、q (実体は、p->next)を参照している。 これはマズイと思います。
コメントに書きましたが、これは、ポインタのコピーなんで問題無そうですね。 (失礼しました)
あとは、fanaさんの回答次第でしょうか。

開放する順序としては、親からでなく、末端の枝から、行うべきでしょう。

--
最初はこれで良いかと思ったが、fanaさんの回答を見て、気になった。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/07/22 16:10

    「push_front形式だけ」ならばtailは不要です。リストの場合は並び順と生成順は同一とは限らないという意味です。

    キャンセル

  • 2021/07/22 16:12

    list_tail という変数が定義されています。

    > LIST *list_tail = NULL;

    キャンセル

  • 2021/07/22 17:14

    先頭または末尾にpush / 先頭からpop のためかな? > list_head/list_tail
    それらがあれば queue と stack が実現できるから。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る