リストを用いたスタックのpush関数のセグメントエラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
drow

リストを用いたスタックのpush関数のセグメントエラー

#1

投稿記事 by drow » 14年前

学校で勉強していた内容を復習していてわからない問題があるのでおしてください。
分からないことは、リストで作ったスタックに対して、pushできる関数を作成しているのですが、セグメントエラーが出て、何を直せばいいのか分からなくて困っています。セグメントエラーはpush関数に入ると起きます。
それから、void push(struct data **top,char key);で使われているダブルポインタについても教えてほしいです。
よろしくお願いします。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct data{
  char key;
  struct data *next;
};

void print_stack_list(struct data *top);
void push(struct data **top,char key);

int main(){

  struct data *top,*new;
  new = (struct data *)malloc(sizeof(struct data));
  new->key = 'a';
  top = new;
  
  //b
  new = (struct data *)malloc(sizeof(struct data));
  top->next = new;

  top->next->key = 'k';
  
 
  //c
  new = (struct data *)malloc(sizeof(struct data));
  top->next->next = new;
  top->next->next->key = 'c';

  printf("check\n");
  // new = (struct data *)malloc(sizeof(struct data));
 
  push(&top,'g'); //**********セグメントエラー
 printf("check\n");
  print_stack_list(top);

  free(new);

  return 0;
}

void push(struct data **top,char key){ //*******************************
  struct data *new;
  new = (struct data *)malloc(sizeof(struct data));
  new->key = key;
  
  while( *top !=NULL){
    *top =(*top)->next;
    }
  (*top)->next = new;
}

void print_stack_list(struct data *top){
  printf("%c",top->key);
   printf("<----TOP\n");
   printf("%c\n",top->next->key);
   printf("%c\n",top->next->next->key);
   printf("%c\n",top->next->next->next->key);
 }

[実行結果]
check
セグメンテーション違反です (コアダンプ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: リストを用いたスタックのpush関数のセグメントエラー

#2

投稿記事 by softya(ソフト屋) » 14年前

前の質問を放置しないようにお願いします。
「ヒープのデータの挿入 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=9215
解決した場合は、最終的なプログラムの投稿と解決チェックをお願いしますね。

で、今回の件ですが前にも出てますがインデントが不十分なのと、説明不足とソースにコメントがあるのが望ましいです。
それからデバッガ(GDB/DDD)は使われたことがありますか?これを使うともっと細かい所がわかるので使ってみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YuO
記事: 947
登録日時: 15年前
住所: 東京都世田谷区

Re: リストを用いたスタックのpush関数のセグメントエラー

#3

投稿記事 by YuO » 14年前

突っ込み所満載のコードですが,問題の一点は,単純にnextに有効な値を代入していないが為にnextがあらぬ所をポイントし,
push内のwhileループで参照したが為にsegmentation faultとなっているのだと思います。

コードはnextに次の要素またはNULLが入っていることを想定しているので,
malloc後,必ずnextにNULLを代入してやることで,このsegmentation faultは解消できます。
# 間違ってもcallocとか使わないこと。ナルポインタ定数の実際の表現が全バイト0だとは規格のどこにも書いていないので。

pushのコードも変だし (なぜ**top?さらに*topを修正するので参照されないオブジェクトができている),
freeも中途半端だし (なぜtopだけ?するならちゃんと全部した方がよいかと。終了直前なのでfreeしない選択肢はありますが,故意にそうしているわけでもないようですし),
softyaさんの書かれているようにデバッガでちゃんと追ってみた方がよいと思います。

初級者
記事: 200
登録日時: 15年前

Re: リストを用いたスタックのpush関数のセグメントエラー

#4

投稿記事 by 初級者 » 14年前

本来push関数で行うような処理を
main関数で行っているところがいまいちな感じがします。

drow

Re: リストを用いたスタックのpush関数のセグメントエラー

#5

投稿記事 by drow » 14年前

失礼しました!未解決問題質問を残しておきながら、このような質問をしてすいません。今後気をつけます。
スタックのpushについて根本的に間違って理解していたせいで上手くいかなかったみたいです。
push関数を直せば上手くいきました。

回答してくださった皆さんありがとうございました。
デバックは普段、ほとんど使っていません。ブレイクポイントのことしか学校で習ってなかったのですが、他に知っておいた方が良い
コマンドがあれば教えて頂けるとありがたいです。これからも、いろいろと世話になると思うのでよろしくお願いします。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct data{
  char key;
  struct data *next;
};

void print_stack_list(struct data *top);
void push(struct data **top,char key);

int main(){
  
  struct data *top,*new;
  new = (struct data *)malloc(sizeof(struct data));
  new->key = 'a';
  top = new;
  
  //b
  new = (struct data *)malloc(sizeof(struct data));
  top->next = new;
  
  top->next->key = 'k';
  
  
  //c
  new = (struct data *)malloc(sizeof(struct data));
  top->next->next = new;
  top->next->next->key = 'c';
  
  printf("check\n");
  // new = (struct data *)malloc(sizeof(struct data));
  
  push(&top,'g');
  printf("check\n");
  print_stack_list(top);
  
  free(new);
  
  return 0;
}


void push(struct data **top,char key){
  struct data *new;
  new = (struct data *)malloc(sizeof(struct data));
  new->key = key;
  
  new->next = (*top);
  (*top) = new;
  
  //free(new);
}

void print_stack_list(struct data *top){
  printf("%c",top->key);
  printf("<----TOP\n");
  printf("%c\n",top->next->key);
  printf("%c\n",top->next->next->key);
}



non
記事: 1097
登録日時: 15年前

Re: リストを用いたスタックのpush関数のセグメントエラー

#7

投稿記事 by non » 14年前

解決ですか?
だめだとおもうけどなぁ。
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: リストを用いたスタックのpush関数のセグメントエラー

#8

投稿記事 by softya(ソフト屋) » 14年前

GDBをエラーが起きた行もわかりますし、ソースコードも表示できます。
変数の内容を確認することでも来ます。
「GDB」
http://www.fireproject.jp/feature/gdb/

あとフロントエンドを使えば便利になりますが、
DDD 日本語がダメなのを忘れててました。
Insight 使ったことがないどうなんだろう。
ExlicpeCDT Windows版ならOK。Linuxは不明。
などがあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 15年前

Re: リストを用いたスタックのpush関数のセグメントエラー

#9

投稿記事 by box » 14年前

drow さんが書きました:解決しました。
では、そのプログラムを使って、10個のデータをスタックに積んでから内容を出力してみてください。
必要に応じて手を加えることは、もちろんありです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る