連結リストのプログラムです
挿入、追加、削除の関数を作り、
switch文で数字を入力して
0=全てを初期化 1=追加 2=ひょうじ 3=削除 9=終了
ができるように実装しました。
0の初期化以外はうまくいきましたが、どうしてもfree関数が機能してくれません
例えば
1 で5、6の数字を追加し、
0 で初期化をし、
2 で表示をしても
初期化されずに5、6の数字が存在しています
free(p);
でなぜ解放されないのか理解できません
質問の内容がわかりにくい場合はお申し付けください
アドバイスよろしくお願いいたします
環境はEasyIDECです
コード #include <stdio.h> #include <stdlib.h> /* 変数headarによって連結リストの先頭が与えられている */ struct CELL { struct CELL *next; /* 次のデータが存在する場所を格納 */ int value; /* セルの値を格納 */ }header; /* 最後の要素は次にくる要素はないため,メンバnextにNULLポインタをセット */ /* 変数headerはリストの先頭を指しており,NULLのときリストは空である */ /* エラーメッセージをプリントしてexitする関数*/ /* ポインタ(アドレス)の先のデータを読み取り専用にする */ void fatal_error(const char *s) { /* fprintf関数を使ってstderrで標準エラーを出力する*/ fprintf(stderr,"%s", s); exit(1); /* 異常終了 */ } /* 追加、挿入する関数 引数aで値を受け取る */ /* 「構造体を指すポインタ->メンバ名」と「(*構造体を指すポインタ.メンバ名)」は同じ。 ドットは実体からアクセスするときに、 アローはポインタ(番地からアクセスするとき)につける。*/ void insert(int a) { /* 構造体のポインタを宣言 */ /* ポインタpは現在のセル,qはpが指すセルの直前のセルを指している */ struct CELL *p,*q,*new; /* 初期化:現在の場所を先頭にする */ p=header.next; /* 境界条件として先頭の次を指すようにしている */ q=&header; /* 先頭を指す */ /* 挿入すべき場所を探す このループを終えたとき、 ①pにはNULLが入っている=変数aの値が全ての要素よりも大きい場合 ②セルへのポインタが入っている=変数aよりも大きいか等しい場合 →新しい要素をpの直前に挿入する必要がある */ while(p!= NULL && a >p->value){ /* ポインタqがポインタpを追いかける形になる qが指すセルとpが指すセルの間に新しいセルが挿入される */ q=p; p=p->next; } /* malloc関数でメモリを確保した分だけnewに入れる */ /* 関数mallocの返す値がNULLであるかチェックする */ if((new=malloc(sizeof(struct CELL))) == NULL) fatal_error("メモリが足りません"); new->next = p; /* 現在の位置を新しいデータが存在する場所にする */ new->value = a; /* 新しいセルの場所に入力した値を入れる */ q->next = new; /* 挿入する場所に値を入れる */ } void print(void) { /* 構造体のポインタを宣言 */ /* 現在いる場所は先頭にしておく */ struct CELL *p; /* 境界条件として先頭の次を指すようにしている */ p=header.next; /* もし先頭がNULLだったら */ if(p == NULL){ fatal_error( "リストは空です\n" ); } /* NULLでない間値を表示する */ while(p!= NULL){ printf( " %d", p->value ); /* 次の値にする */ p = p->next; } printf("\n"); } /* 削除する関数 */ int DelCell(int c) { /* 構造体のポインタを宣言 */ /* ポインタpは現在、qはpが指すセルの直前のセルを指している */ struct CELL *p,*q; struct CELL *x=NULL; /* 初期化:現在の場所を先頭にする */ p=header.next; /* 境界条件として先頭の次を指すようにしている*/ q=&header; while(p!=NULL&&p->value!=c){ q=p; p=p->next; } /* もし先頭がNULLまたは指定した値の方が大きい場合 */ if(p==NULL || p->value<c){ /* 削除する値が見つからないとして1を返す */ free(x); return 1; /* 指定した値が見つかったら */ }else{ x=q->next; q->next=x->next; /* xで指定されたセルの内容を取り出して解放、削除 削除する値が見つかったとして0を返す*/ free(x); return 0; } } int main(void) { int i; /* ループ用変数 */ int n; /* 配列の要素数 */ int a,c; /* 追加,削除に使う変数 */ int x; /* 関数の戻り値用 */ int mn=0; /* メニュー選択用 */ struct CELL *p=NULL; struct CELL *q=NULL; q=&header; printf("連結リストをします\n"); do{ printf("メニューを選んでください\n0=全てを初期化 1=追加 2=ひょうじ 3=削除 9=終了\n"); scanf("%d",&mn); switch(mn){ case 0: printf("初期化します\n"); free(p); q=NULL; break; case 1: printf("新たに1つ数字を連結します。数字を入力してください\n"); scanf("%d",&a); insert(a); break; case 2: printf("リストを出します\n"); /* リストの要素の値を表示する */ print(); break; case 3: printf("リストの中の削除する数字を入力してください\n"); scanf("%d",&c); x=DelCell(c); if(x==1){ printf("NotExist\n"); } else{ printf("Done\n"); } break; case 9: printf("終了します\n"); break; default: printf("エラー:数字を入力してください\n"); scanf("%d",&mn); } }while (mn !=9); return 0; }
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/12 14:13