• ベストアンサー

ポインタを使った連結リストへの挿入

siteiで指定されているポインタの直後に要素xを挿入する関数insertをポインタの連結リストを用いて作成したのですが、実行するとセグメンテーション違反がでて上手く動きません。何処に問題があるのでしょうか?topの初期値が不定になるのが問題と思い、topをNULLで初期化して実行してみたのですが、結果は変わりませんでした。 宜しければ回答または問題点を指摘していただけますでしょうか?宜しくお願いします。 typedef struct{ int data; struct DATA *next; }DATA; DATA top; int insert(int x,DATA *sitei) { DATA *p,*buf; p=⊤ while( p!=NULL && p!=sitei) p=p->next; buf=malloc(sizeof(DATA)); buf->next=p->next; p->next=buf; buf2->data=x; return 0; }

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

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>while( p!=NULL && p!=sitei) >p=p->next; なんでループまわすんですか? siteiの次なんですよね。新しい要素の挿入位置は。 buf=malloc(sizeof(DATA)); buf->next=sitei->next; sitei->next->next=buf; buf->data=x; これだけで問題ないような。 で、siteiに不正な値やNULLが入ってくる可能性があるのですか? そういうことですとエラーチェックがないんで問題ありですけど。

linuxbeginner
質問者

お礼

返事ありがとうございます。 >>buf=malloc(sizeof(DATA)); >>buf->next=sitei->next; >>sitei->next=buf; >>buf->data=x; としたところ無事に動作しました。このプログラムでは不正な値は入ってこないので、エラーチェックの必要は ありません。よくよく考えてみるとwhileループを回す必要はありませんでしたね。 ご回答ありがとうございました。

その他の回答 (2)

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

>while( p!=NULL && p!=sitei) >p=p->next; このループは p == NULL で抜けますが,その時 >buf->next=p->next; で、(DATA *)NULL->next が実行されます。 もっとも、#2の回答の方の言う通り、 そもそもループしなければこの問題が起きませんが。 ただ、指定の次にいれるなら、 >sitei->next->next=buf; は sitei->next = buff; だと思いますが。 top自体は、グローバルかスタティック変数に見えますので, 多分 0 で初期化されているとは思います。

linuxbeginner
質問者

お礼

返事ありがとうございます。 >>>buf->next=p->next; >>で、(DATA *)NULL->next が実行されます。 ここで問題が発生するかもしれませんね。2で回答していただいた答えを使うことにして、whileループは使わないようにします。 ありがとうございました。

  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.1

>topの初期値が不定になるのが問題と思い、topをNULLで初期化して実行してみたのですが、 DATA top; top.next=NULL; としてみたということでしょうか?これは必須ですね。 あと最後の方は、 buf->data=x; のタイプミスですよね? 他には見たところおかしそうなところは無いので、呼び出し側の問題かもしれません。 後はデバッガを使うか要所要所にprintfを入れてみるかですね。

linuxbeginner
質問者

お礼

返事ありがとうございます。 >>後はデバッガを使うか要所要所にprintfを入れて >>みるかですね。 printfで表示させるといった手段は手軽にできますし、有効ですね。最後の方はご指摘通りにタイプミスです。アドバイスありがとうございました。

関連するQ&A

  • 構造体のポインタにNULLが入らない

    typedef struct tag{ int number; char name[10]; struct tag *next; }DATA; という構造体があって、 DATA *p; と宣言し、 p->next == NULL; とすることはできないんですか? セグメンテーション違反になってしまうのですが。 pが指すnextにNULLを入れるにはどうしたらいいのでしょうか?

  • 連結リストをソート

    学校の課題なんですが正直手も足も出ません。 どういった流れで作成すればいいんでしょうか。 1.連結リストにデータ(文字列)をソートされた順序に追加するようなプログラムを作成する. 2.連結リストのデータを順にプリントするプログラムを作成する。 3.セルをキーとそれに対応する値を含めるように拡張し、与えられたキーを持つセルを探索して  それに対する値を返すプログラムを作成する。 課題を解く際には以下のプログラムを参考にする #include <stdio.h> struct element{ char data; struct element *next; }; struct elements *new() { return((struct element *)malloc(sizeof(struct element))); } struct element *create() { struct element *p; p=new(); p->next=NULL; return(p); } void insert(struct element *l,int k,char item) { struct element *p; if(k>1) insert(l->next,k-1,item); else{ p=new(); p->data=item; p->next=p; l->next=p; } } void delete(struct element *l,int k) { if(k>1) delete(l->next,k-1); else l->next=l->next->next; } char access(struct element *l,int k) { if(k>1) return(access(l->next,k-1)); else return(l->next->data); }

  • 連結リストについて

    連結リストについて アルゴリズムの本を買って勉強しているのですが、わからない箇所がありまして。 構造体宣言で (1)struct CELL { struct CELL *next; int val; }; (2)struct CELL { struct CELL *next; int val; }*header; 順番をたどって行く書き方で struct CELL *p; for (p=header; p!=NULL; p=p->next) printf("%d\n", p->value); なぜこれでp->valueの値が変動していくのですか? それと上記の(1)の書き方でこのforを回すとき、headerはどのように定義すればよいのですか? よろしくお願いします。

  • 線形リストに挿入するプログラム

    連結リストに要素を挿入する関数 insert( ) を関数を定義して,以下の条件の下で整数型の要素を連結リストに挿入するプログラムを作成しなければならないのですが、関数insert部分が見当がつきません. 回答よろしくおねがいします。 条件 1. 関数名を insert( ) とする. 2. 連結リストの先頭ノードを指すポインタ(*head)と,リストに挿入する要素(data)を引数とする. 3. 連結リストの先頭ノードを指すポインタ(*head)からたどって,要素がリスト内で降順(大きいものから小さいものへの順)となる位置に要素を挿入する. 4. 引数で示された要素が既にリストに存在する場合には,要素の挿入は行なわない. #include <stdio.h> #include <stdlib.h> typedef struct __cell { int data; struct __cell *next; } CELL; CELL *insert(CELL *head, int data); void showList(CELL *head); int main(void) { CELL *head; head = NULL; head = insert(head, 5); showList(head); head = insert(head, 2); showList(head); head = insert(head, 6); showList(head); head = insert(head, 4); showList(head); head = insert(head, 6); showList(head); head = insert(head, 4); showList(head); head = insert(head, 1); showList(head); return 0; } CELL *insert(CELL *head, int data) { /*ここで関数 insert( ) を定義します*/ } void showList(CELL *head) { CELL *p; for(p=head ; p!=NULL ; p=(*p).next) { printf("%d -> ", (*p).data); } printf("fin\n"); }

  • リストがわかりません。

    下のプログラムはリストに昇順になるように 入力された要素を挿入するプログラムですが、うまくいきません。どうか教えてください。 #include<stdio.h> static int count; struct node_tag{ int data; struct node_tag *next; }; typedef struct node_tag node_t; node_t *insert_node( node_t *t, int d ); node_t *print_list( node_t *r ); int main( void ) { node_t root; int data; root.next = NULL; for ( ;; ) { printf( "> " ); if ( scanf( "%d", &data ) != 1 ) break; insert_node( &root, data ); print_list( &root ); } return; } node_t *insert_node( node_t *t, int d ) { node_t *new_node; new_node = (node_t *)malloc( sizeof(node_t) ); if( new_node == NULL ) return NULL; if(count == 0) { new_node -> data = d; new_node -> next = NULL; t -> next = new_node; count++; } else { for(; t -> next != NULL; t = t -> next) { if(t -> next -> data >= d) break; } if(t -> next -> data == d) return; else if(t -> next -> data > d) { new_node -> data = d; new_node -> next = t -> next; t -> next = new_node; } else if(t -> next == NULL) { new_node -> data = d; t -> next = new_node; new_node -> next = NULL; } } return new_node; } node_t *print_list( node_t *r ) { node_t *p; printf("[ "); for( p = r -> next; p != NULL; p = p -> next) { printf("%d ", p -> data); } printf("]\n"); }

  • リス;ト構造のポインタ

    struct list{ int data; struct list *next; }; struct list *cons(int x,struct list *n){ struct list *ans; ans=(struct list*)malloc(sizeof(struct list)); if(ans!=null) ans->date=x; ans->next=n; } return ans;} void main(){ int x; struct list *top=NULL; struct list **tail=&top; while(scanf("%d",&x)==1){ *tail=cons(x,NULL);  tail=&((*tail)->next):         }  入力した順にリストに追加されるプログラムらしいのですが、void main(){}の中のプログラムの動きが よく分かりません。このプログラムの動作の流れを簡単に教えてください。漠然とした質問カと思いますが よろしくお願いします。

  • 双方向リストのバブルソートについて

    双方向リストをバブルソートを用いてソートしたいです。 下記がプログラム(一部)ですが、ソートした後にリスト表示すると 無限ループに陥ります。 どこがいけないのでしょうか。 #include <stdio.h> #include <stdlib.h> struct cell{ int data; struct cell *next, *prev; }; void insert_head(struct cell **head, int num){ struct cell *p, *p1; p = *head; p1 = make_cell(); *head = p1; p1->data = num; p1->next = p; if(p1->next != (struct cell *)NULL){ p1->next = p; p->prev = p1; } } void print_list(struct cell *head){ struct cell *p; p = head; printf("data = \n"); while(p != (struct cell *)NULL){ printf("%d\n", p->data); p = p->next; } } void sort_list(struct cell **head){ struct cell *p, *p2; int i, n; n = 0; p = *head; while(p->next != (struct cell *)NULL){ p = p->next; n++; } for(i = 0, p = *head; i < n-2; i++){ if(p->data > p->next->data){ if(p == *head){ *head = p->next; }else{ p->prev->next = p->next; } p2 = p->next; p->next = p->next->next; p->next->next = p; p->next->next->prev = p; p->next->prev = p->prev; p->prev = p2; }else p = p->next; } } int main(void){ struct cell *head = (struct cell *)NULL; int n; while(1){ printf("1:Insert head 2:Insert tail 3:Delete 4:List 5:Sort 6:Exit\n"); scanf("%d", &n); switch(n){ case 1: printf("num = "); scanf("%d", &n); insert_head(&head, n); break; case 2: printf("num = "); scanf("%d", &n); insert_tail(&head, n); break; case 3: printf("num = "); scanf("%d", &n); delete_cell(&head, n); break; case 4: print_list(head); break; case 5: sort_list(&head); break; case 6: return 0; break; } } }

  • パスを含むファイルリストを表示する際、 ASCIIコード順になるように

    パスを含むファイルリストを表示する際、 ASCIIコード順になるようにソートして表示するようにするプログラムを作っているのですが、リストの仕組がいまいちよくわからず、うまくソートできません。 /* insert_dirent_cell(): セルをリストの先頭に追加する * 引数: head -- リストの先頭のセルへのポインタ * cell -- リストに加えたいセルへのポインタ * 戻り値: リストの先頭のセルへのポインタ */ struct dirent_cell *insert_dirent_cell(struct dirent_cell *head,struct dirent_cell *cell) { struct dirent_cell *ins_buf; //最初に挿入 if(head == NULL) { head = cell; return cell; } //先頭に挿入 if(strcmp(head->name, cell->name) > 0) { cell->next = head; head->next = cell->next->next; return cell; } //途中に挿入 ins_buf = head; while(ins_buf->next != NULL) { if(strcmp(ins_buf->next->name, cell->name) > 0) { cell->next = ins_buf->next; ins_buf->next->next = cell->next->next; return cell; } ins_buf = ins_buf->next; } //最後に挿入 ins_buf->next = NULL; cell->next = ins_buf; return cell; }

  • 線形リスト

    こんにちわ。今、大学で線形リストの勉強してるのですがよくわかりません。 ↓のプログラムで (1)10個のIDを受け取って受け取った順にリストを作るプログラム(各要素の値のアドレスとそのnextの値を表示してリストになっていることを確認する。) (2) (1)のプログラムを拡張して、リストを作ったあと、1から10までの間の整数nを入力として受け取り、リストのn番目の要素のIDを表示プログラムを書け。 の2つのことをしたいんですけど、どのようにすればいいのですか?どなたか回答おねがいします。 #include<stdio.h> #include<stdlib.h> struct list{ int ID; struct list *next; }; int main(int argc, char* argv[]) { struct list *top; top=(struct list *)malloc(sizeof(struct list)); //struct list 型の大きさの領域を1つ確保 //topがそこを指している状態にする //printf("IDを10個入力してください"); if(top == NULL){ //メモリが足りないと値がNULLになってします printf("メモリは確保できません\n"); exit(1); //強制終了。プログラムはココで終わってしまいます } top->next=NULL; top->ID=1; //ポインタtopが指している構造体のIDの値を変えている top->next=(struct list*)malloc(sizeof(struct list)); //もう1つ作ります //top->next==NULL (メモリ確保に失敗)の処理は省略 (top->next)->next=NULL; (top->next)->ID=5; //これで下図のような状態になります; return 0; }

  • C言語 リスト

    (1) /* list.c */ #include <stdio.h> #include <stdlib.h> struct node { int num; struct node *next; }; main() { struct node *head, *p; int x; head = NULL; while(scanf("%d",&x) != EOF) { p = (struct node *)malloc(sizeof(struct node)); p->num = x; p->next = head; head = p; } // リストの要素のnumの値を先頭から順に表示する p=head; while(p!=NULL) { printf("%d\n" ,p->num); p = p->next; } } (2) struct node *q; q = head; while(q->next != NULL) q = q->next; (1)を(2)を使い新しいノードをリストの最後に追加するようにしたいのですが どう書いたら良いのか教えていただきたいです

専門家に質問してみよう