みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

線形リスト(C言語)

線形リストでn番目のIDを表示するプログラムを作っていますが、なぜか実行すると強制終了してしまいます。
コンパイルエラーは起きていないので、原因がさっぱりわかりません。
どなたかご教授お願いします。
#include <stdio.h>
#include <stdlib.h>

struct list{
int ID;
struct list *next;
};

int main(void)
{
struct list *top, *a;
int i, n, x;

a = NULL;

for(i = 1; i < 11; i++) {
printf("%d番目のIDを入力: " ,i);
scanf("%d" ,&x);

top = (struct list *)malloc(sizeof(struct list));

top->ID = x;
top->next = a;

a = top;
}

printf("何番目のIDを表示しますか: ");
scanf("%d" ,&n);

for(i = 1; i < 11; i--) {
if(i == n) printf("%d" ,top->ID);
top = top->next;
}

free((top->next->next->next->next->next->next->next->next)->next);
free((top->next->next->next->next->next->next->next)->next);
free((top->next->next->next->next->next->next)->next);
free((top->next->next->next->next->next)->next);
free((top->next->next->next->next)->next);
free((top->next->next->next)->next);
free((top->next->next)->next);
free((top->next)->next);
free(top->next);
free(top);

return 0;
}

投稿日時 - 2006-11-21 12:21:36

QNo.2552999

すぐに回答ほしいです

質問者が選んだベストアンサー

質問者さんが線形リストの構造について理解していないのが原因だと思います。
プログラムを読んでいて配列と混同しているところが見受けられます。
線形リストはLIFOなので一度とり出してしまったら
先頭のアドレスを確保しておかない限りも元に戻りません。
取り出す操作とは top = top->next; です。
なので最後の開放の部分などは何も入っていない入れ物を
どんどん解放しようとしています。
for文の前にa=top;としてループ終了時にtop=a;等とすれば可能です。
あとこのプログラムでは入力を求める際の1番目のIDと出力を求める際の1番目のIDは異なりますよ。(理由はLIFOだから)
同じ1番目を指したいのなら(NO.3さんのを借用します)
a=top;
i=10; // カウンター初期化
while( top != NULL ){
if( i == n ) {
printf("%d", top->ID);
}
i--;
top = top->next;
}
top=a;
//領域解放
while( top != NULL ){
a=top;
top=top->next;
free(a);
}
てなかんじ。
授業をちゃんと聞きましょう。

投稿日時 - 2006-11-21 13:24:02

お礼

ご回答ありがとうございます。
とてもためになるご指導ありがとうございます。
なんとか完成させることができました。
授業のときは睡魔に負けていた気がします・・・

投稿日時 - 2006-11-22 11:50:22

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

後半のprintしているfor文が、i-- とカウンターデクリメントになっているので無限ループしてるとか?

リストは末尾までチェックするようにしたほうが良いので
i=1; // カウンター初期化
while( top != NULL ){
if( i == n ) {
printf("%d", top->ID);
}
i++;
top = top->next;
}

としたほうが良いと思います

投稿日時 - 2006-11-21 12:48:23

お礼

ご回答ありがとうございます。
>リストは末尾までチェックするようにしたほうが良いので
そうですね、考えてませんでした。やはり、配列のように考えてしまっていた感じがします。

投稿日時 - 2006-11-22 11:52:32

ANo.2

リスト構造は答えを貰っても、ちゃんと理解してないと
使えませんよ。
なので、
参考URLを貼っておきます。

ちなみに
http://okwave.jp/qa2550122.html
ここにも同じソースで同じ質問がありますので、
参考にしてください。

参考URL:http://www.kyoto-su.ac.jp/~yamada/ap/list.html

投稿日時 - 2006-11-21 12:47:05

お礼

ご回答ありがとうございます。
リスト構造は構造自体はイラストで考えるとわかる気がしますが、それをどうやるかが難しいです・・・

投稿日時 - 2006-11-22 11:54:25

ANo.1

IDを表示する処理の、

> for(i = 1; i < 11; i--) {
> if(i == n) printf("%d" ,top->ID);

の間に、

iを表示、nを表示、topのポインタを表示する処理などを入れてみてください。

投稿日時 - 2006-11-21 12:44:21

お礼

ご回答ありがとうございます。
処理を入れてみたところ、なんとなく変な感じがしました。
もうちょっと調べてみます。

投稿日時 - 2006-11-22 11:55:50

あなたにオススメの質問