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

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

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

881閲覧

連結リストを実装したいのですが、segmentation fault: 11と出てしまいます。

goro_gnm

総合スコア42

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/06/13 12:44

前提・実現したいこと

以下の命令を受けつける双方向連結リストを実装したいです。

insert x: 連結リストの先頭にキー x を持つ要素を継ぎ足す。
delete x: キー x を持つ最初の要素を連結リストから削除する。そのような要素が存在しない場合は何もしない。
deleteFirst: リストの先頭の要素を削除する。
deleteLast: リストの末尾の要素を削除する。

以下入力例

7 insert 5 insert 2 insert 3 insert 1 delete 3 insert 6 delete 5

以下出力例

6 1 2

この機能の実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

以下の3行の入力後、segmentation fault: 11のメッセージが出てしまいます。何を改善したらこれはなくなるのでしょうか。

2 delete 2 insert 1 Segmentation fault: 11

該当のソースコード

c++

1#include<cstdio> 2#include<cstdlib> 3#include<cstring> 4 5struct Node{ 6 int key; 7 Node *next, *prev; 8}; 9 10Node *nil; 11 12Node* listSearch(int key){ 13 Node *cur = nil->next;// 14 while(cur != nil && cur->key != key ){ 15 cur = cur->next; 16 } 17 return cur; 18} 19 20void init() { 21 nil = (Node *)malloc(sizeof(Node)); 22 nil->next = nil; 23 nil->prev = nil; 24} 25 26void insert(int key){ 27 Node *x = (Node *)malloc(sizeof(Node)); 28 x->next = nil->next; 29 x->prev = nil; 30 nil->next = x; 31 nil->next->prev = x; 32} 33 34void deleteNode(Node *t){ 35 if (t == nil) return; 36 t->prev->next = t->next; 37 t->next->prev = t->prev; 38 free(t); 39} 40 41void deletefirst(){ 42 deleteNode(nil->next); 43 } 44 45void deletelast(){ 46 deleteNode(nil->prev); 47} 48 49void deletekey(int key){ 50 deleteNode(listSearch(key)); 51} 52 53void printlist(){ 54 Node *cur = nil->next; 55 int isf = 0; 56 while(1){ 57 if(cur == nil) break; 58 if(isf++ > 0) printf(""); 59 printf("%d", cur->key); 60 cur = cur->next; 61 } 62 printf("\n"); 63} 64 65int main(){ 66 int i, n, key; 67 scanf("%d", &n); 68 //int size = 0; 69 //int np = 0, nd = 0; 70 char com[20]; 71 for(i=0;i<n;i++){ 72 scanf("%s%d", com, &key); 73 if(com[0] == 'i'){ insert(key); 74 //np++; size++; 75 } 76 else if(com[0] == 'd'){ 77 if(strlen(com) > 6) deletefirst(); 78 else if(com[6] == 'F') deletelast(); 79 }else{ 80 deletekey(key); //nd++; 81 } 82 //size--; 83 } 84 85 printlist(); 86 return 0; 87 88}

補足情報

AOJのアルゴリズムとデータ構造の問題です。
ALDS1_3_C: Doubly Linked List

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

init を呼んでいないからでは?

投稿2019/06/13 12:53

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/06/13 13:06

とりあえず聞かれたことだけ答えましたが、他にも怪しいところがいくつかあります。よくソースを追ってください。
goro_gnm

2019/06/13 14:25

回答ありがとうございます。 init 抜けていました。 また他に自分が気づいたところを直したところ、insert delete のみの命令であれば実行できるようになりました。 ただ deleteFirst deleteLast が命令に入るとできません。 このscanfの方法だと、命令のあとに int が入らないことに原因があるように思います。だとすると、どのようにしたらいいのでしょうか。 cを触ったことがある程度でc++を始めたばかりです。よろしくお願いします。 #include<cstdio> #include<cstdlib> #include<cstring> struct Node{ int key; Node *next, *prev; }; Node *nil; Node* listSearch(int key){ Node *cur = nil->next;// while(cur != nil && cur->key != key ){ cur = cur->next; } return cur; } void init() { nil = (Node *)malloc(sizeof(Node)); nil->next = nil; nil->prev = nil; } void insert(int key){ Node *x = (Node *)malloc(sizeof(Node)); x->key = key; x->next = nil->next; nil->next = x; nil->next->prev = x; x->prev = nil; } void deleteNode(Node *t){ if (t == nil) return; t->prev->next = t->next; t->next->prev = t->prev; free(t); } void deletefirst(){ deleteNode(nil->next); } void deletelast(){ deleteNode(nil->prev); } void deletekey(int key){ deleteNode(listSearch(key)); } void printlist(){ Node *cur = nil->next; int isf = 0; while(1){ if(cur == nil) break; if(isf++ > 0) printf(""); printf("%d", cur->key); cur = cur->next; } printf("\n"); } int main(){ int i, n, key; scanf("%d", &n); //int size = 0; //int np = 0, nd = 0; init(); char com[20]; for(i=0;i<n;i++){ scanf("%s%d", com, &key); if(com[0] == 'i'){ insert(key); //np++; size++; } else if(com[0] == 'd'){ if(strlen(com) > 6){ if(com[6] == 'F') deletefirst(); else if(com[6] == 'L') deletelast(); }else{ deletekey(key); //nd++; } //size--; } } printlist(); return 0; }
Zuishin

2019/06/13 14:48 編集

この質問は「連結リストを実装したいのですが、segmentation fault: 11と出てしまいます。」で、それは解決したと思います。他にも問題はありますが、それはまた別の問題なので、まず自分でソースを追ってデバッグしてください。それでわからなければまた新たに質問してください。 連結リストが欲しいというだけなら std::list でいいはずです。学習のために組んでいるんですよね? デバッグを全部人にやらせたのでは学習効果が薄いのでは?
pepperleaf

2019/06/13 14:28

質問文、更新しませんか? インデントが崩れて見ずらいです。
goro_gnm

2019/06/14 04:12

>Zuisjin さん 新たな質問にしなかったのは私の怠惰でした。失礼しました。 回答ありがとうございました。 私は自分である程度考えてわからないときはデバックをしてもらった方が効率がいいかなと思っておりますが、まあ人それぞれですね。 >pepperleaf さん 私も投稿してから気づきました。ご指摘ありがとうございます。
Zuishin

2019/06/14 04:16

自分でしないなら std::list を使うのが一番効率的ですね。既に完成してるので。完成した連結リストのソースも探せばいくらでもあるはずです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問