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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

C++

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

Q&A

解決済

1回答

995閲覧

線形リストでセグメントエラーになってしまいます。

apeirogon0813

総合スコア117

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

C++

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

0グッド

0クリップ

投稿2019/01/30 05:30

編集2019/01/30 05:50

前提・実現したいこと

struct node( int element, struct node next);
struct node
p;
のようなノードで線形リストで
p

[0]->[1]->[2]
というよなelementの要素が入ったリストを作り
while(p != NULL) {
p = p->next;
}
とし
p->element = 2のとき
p = p->next;
とするとセグメントエラーになってしまいました。
これはNULLを参照してしまったからでしょうか?

いつもはこの様な方法でもおそらくNULLがそのまま代入されてセグメントエラーになってなかったと思うのですが
今回のプログラムではセグメントエラーになってしまいました。

関数dijkstraの局所局所にprint文を入れてどこでエラーなるかチェックしたところ
adjlist[cur] = adjlist[cur]->next;の手前まで出力されていたためこれが原因かと思っていました。。

C

1#include<stdio.h> 2#include<stdlib.h> 3#include<limits.h> 4#define ROSENZU "rosenzu.txt" /* 路線図データファイル */ 5#define SETMAX 10600 /* 集合の要素数の最大値 (駅の数) */ 6char buf[256]; /* 入力された文字列を格納するグローバル変数 */ 7 8int dist[SETMAX]; /* 指定された駅から各駅までの最短距離を格納するグローバル変数 */ 9 10struct node { int eki, rosen, kyori; struct node *next; }; 11struct set { int elements[SETMAX]; int size; }; 12 13void init_set(struct set *p, int n, int e) { 14 int i, j=0; 15 p->size = n-1; 16 for(i = 0; i < p->size; i++) { 17 if(j == e) 18 j++; 19 p->elements[i] = j++; 20 } 21} 22 23int delete_min(struct set *p) { 24 int i=0, j, min = dist[p->elements[0]];//一回ループを省力するため添字0の値を\ 25代入しておく 26 if(p->size == 0) //空集合の場合 27 return -1; 28 else 29 for(j=1; j < p->size; j++) { //一番小さい値の添字の探索 30 if(dist[p->elements[j]] < min) { 31 min = dist[p->elements[j]]; 32 i = j; 33 } 34 } 35 min = p->elements[i]; //minにはreturnする要素を格納 36 p->elements[i] = p->elements[p->size -1]; //最小値の場所に格納 37 p->size--; 38 return min; 39} 40 41//一方向の経路の挿入 42struct node* insert_edge(struct node *list, int eki, int rosen, float kyori) { 43 struct node *n; 44 n = (struct node*)malloc(sizeof(struct node)); 45 n->eki = eki; 46 n->rosen = rosen; 47 n->kyori = kyori; 48 n->next = list; 49 return n; 50} 51 52void add_edge(struct node *adjlist[], int eki1, int eki2, int rosen, int kyori) { 53 adjlist[eki1] = insert_edge(adjlist[eki1], eki2, rosen, kyori); 54 adjlist[eki2] = insert_edge(adjlist[eki2], eki1, rosen, kyori); 55} 56 57int dijkstra(struct node *adjlist[], int eki1, int eki2, int ekisu) { 58 int i, cur; //cur:直前に最短距離が確定した駅の変数 59 struct set unknown; 60 for(i=0; i<ekisu; i++) { //到達可能かわからない要素をINT_MAXにする 61 if(i == eki1) 62 dist[i] = 0; 63 else 64 dist[i] = INT_MAX; 65 } 66 cur = eki1; 67 init_set(&unknown, ekisu, cur); 68//セグメントエラー確認のためここでリストを巡回させるとやはりエラーになった////////////////////// 69 while(adjlist[eki1] != NULL) { 70 adjlist[eki1] = adjlist[eki1]->next; 71 printf("%d->%d\n",adjlist[eki1],adjlist[eki1]->next); 72 } 73 //////////////////////////////////////////////////////////////// 74 75 76 while(unknown.size !=0 || cur != eki2) { 77 while(adjlist[cur] != NULL) { 78 printf("dist[%d] + adjlist[%d]->kyori < dist[%d] = %d + %d < %d\n",cur,cur,adjlist[cur]->eki,dist[cur],adjlist[cur]->kyori,dist[adjlist[cur]->eki]); 79 if(dist[cur] + adjlist[cur]->kyori < dist[adjlist[cur]->eki]) 80 dist[adjlist[cur]->eki] = dist[cur] + adjlist[cur]->kyori; 81 printf("next\n"); 82printf("eki = %d, next = %d\n", adjlist[cur]->eki, adjlist[cur]->next->eki); 83 printf("%d\n",adjlist[cur]->next); 84 adjlist[cur] = adjlist[cur]->next; //この前までのprintは出力された 85 printf("eki = %d, next = %d\n", adjlist[cur]->eki, adjlist[cur]->next->eki); 86 } 87 printf("srgsrgs\n"); 88 cur = delete_min(&unknown); //集合unknownの最短距離の駅をcurに格納 89 printf("are\n"); 90 } 91 printf("1\n\n"); 92 return dist[eki2]; 93} 94 95int main() { 96 int eki1, eki2, rosen, ekisu, i, kyori; 97 FILE *fp = fopen(ROSENZU,"r"); /* 路線図ファイルを読む準備 */ 98 fscanf(fp, "%d ", &ekisu); /* 1行めの駅数を読取り */ 99 struct node *adjlist[ekisu]; 100 /* 隣接リスト表現を初期化.すべての頂点に対する隣接リストを空にする */ 101 for(i=0;i<ekisu;++i) adjlist[i] = NULL; 102 while(fgets(buf,sizeof(buf),fp)!=NULL) { 103 /* 隣り合う駅の情報を読取り */ 104 sscanf(buf, "%d:%d:%d:%d␣", &eki1, &eki2, &rosen, &kyori); 105 /* そのデータを隣接リスト表現のグラフに追加 */ 106 add_edge(adjlist, eki1, eki2, rosen, kyori); 107 } 108 fclose(fp); 109 scanf("%d %d ", &eki1, &eki2); 110 printf("%d\n", dijkstra(adjlist, eki1, eki2, ekisu)); 111 /* for(i=0;i<ekisu;++i) 112 if(dist[i] < INT_MAX) 113 printf("%d: %d\n", i, dist[i]); */ 114 return 0; 115} 116

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

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

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

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

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

y_waiwai

2019/01/30 05:35

ソースコードを提示してください。 バグはあなたの思っているところではありませんw
apeirogon0813

2019/01/30 05:43

```C #include<stdio.h> #include<stdlib.h> #include<limits.h> #define ROSENZU "rosenzu.txt" /* 路線図データファイル */ #define SETMAX 10600 /* 集合の要素数の最大値 (駅の数) */ char buf[256]; /* 入力された文字列を格納するグローバル変数 */ int dist[SETMAX]; /* 指定された駅から各駅までの最短距離を格納するグローバル変数 */ struct node { int eki, rosen, kyori; struct node *next; }; struct set { int elements[SETMAX]; int size; }; void init_set(struct set *p, int n, int e) { int i, j=0; p->size = n-1; for(i = 0; i < p->size; i++) { if(j == e) j++; p->elements[i] = j++; } } int delete_min(struct set *p) { int i=0, j, min = dist[p->elements[0]];//一回ループを省力するため添字0の値を\ 代入しておく if(p->size == 0) //空集合の場合 return -1; else for(j=1; j < p->size; j++) { //一番小さい値の添字の探索 if(dist[p->elements[j]] < min) { min = dist[p->elements[j]]; i = j; } } min = p->elements[i]; //minにはreturnする要素を格納 p->elements[i] = p->elements[p->size -1]; //最小値の場所に格納 p->size--; return min; } //一方向の経路の挿入 struct node* insert_edge(struct node *list, int eki, int rosen, float kyori) { struct node *n; n = (struct node*)malloc(sizeof(struct node)); n->eki = eki; n->rosen = rosen; n->kyori = kyori; n->next = list; return n; } void add_edge(struct node *adjlist[], int eki1, int eki2, int rosen, int kyori) { adjlist[eki1] = insert_edge(adjlist[eki1], eki2, rosen, kyori); adjlist[eki2] = insert_edge(adjlist[eki2], eki1, rosen, kyori); } int dijkstra(struct node *adjlist[], int eki1, int eki2, int ekisu) { int i, cur; //cur:直前に最短距離が確定した駅の変数 struct set unknown; for(i=0; i<ekisu; i++) { //到達可能かわからない要素をINT_MAXにする if(i == eki1) dist[i] = 0; else dist[i] = INT_MAX; } cur = eki1; init_set(&unknown, ekisu, cur); while(adjlist[eki1]->next != NULL) { adjlist[eki1] = adjlist[eki1]->next; printf("%d->%d\n",adjlist[eki1],adjlist[eki1]->next); } while(unknown.size !=0 || cur != eki2) { while(adjlist[cur]->next != NULL) { printf("dist[%d] + adjlist[%d]->kyori < dist[%d] = %d + %d < %d\n",cur,cur,adjlist[cur]->eki,dist[cur],adjlist[cur]->kyori,dist[adjlist[cur]->eki]); if(dist[cur] + adjlist[cur]->kyori < dist[adjlist[cur]->eki]) dist[adjlist[cur]->eki] = dist[cur] + adjlist[cur]->kyori; printf("next\n"); printf("eki = %d, next = %d\n", adjlist[cur]->eki, adjlist[cur]->next->eki); printf("%d\n",adjlist[cur]->next); adjlist[cur] = adjlist[cur]->next; printf("eki = %d, next = %d\n", adjlist[cur]->eki, adjlist[cur]->next->eki); } printf("srgsrgs\n"); cur = delete_min(&unknown); //集合unknownの最短距離の駅をcurに格納 printf("are\n"); } printf("1\n\n"); return dist[eki2]; } int main() { int eki1, eki2, rosen, ekisu, i, kyori; FILE *fp = fopen(ROSENZU,"r"); /* 路線図ファイルを読む準備 */ fscanf(fp, "%d ", &ekisu); /* 1行めの駅数を読取り */ struct node *adjlist[ekisu]; /* 隣接リスト表現を初期化.すべての頂点に対する隣接リストを空にする */ for(i=0;i<ekisu;++i) adjlist[i] = NULL; while(fgets(buf,sizeof(buf),fp)!=NULL) { /* 隣り合う駅の情報を読取り */ sscanf(buf, "%d:%d:%d:%d␣", &eki1, &eki2, &rosen, &kyori); /* そのデータを隣接リスト表現のグラフに追加 */ add_edge(adjlist, eki1, eki2, rosen, kyori); } fclose(fp); scanf("%d %d ", &eki1, &eki2); printf("%d\n", dijkstra(adjlist, eki1, eki2, ekisu)); /* for(i=0;i<ekisu;++i) if(dist[i] < INT_MAX) printf("%d: %d\n", i, dist[i]); */ return 0; } ```
y_waiwai

2019/01/30 05:44

ここではコードが見づらいので、質門の方を編集し、<code>ボタンで、出てくる’’’の枠の中にコードを貼り付けてください
apeirogon0813

2019/01/30 05:45

関数dijkstraの局所局所にprint文を入れてどこでエラーなるかチェックしたところ adjlist[cur] = adjlist[cur]->next;の手前まで出力されていたためこれが原因かと思っていました。。
y_waiwai

2019/01/30 05:48

そこらへんの情報ももらさず質問に追記していただければ、解決も早いかと思いますです
guest

回答1

0

ベストアンサー

c

1while(adjlist[eki1] != NULL) { 2 adjlist[eki1] = adjlist[eki1]->next; 3 printf("%d->%d\n",adjlist[eki1],adjlist[eki1]->next); 4}

↓こうじゃない?

c

1while(adjlist[eki1] != NULL) { 2 printf("%d->",adjlist[eki1]); 3 adjlist[eki1] = adjlist[eki1]->next; 4 if (adjlist[eki1] != NULL){ 5 printf("%d",adjlist[eki1]); 6 } 7 printf("\n"); 8}

じゃない?

投稿2019/01/30 05:59

編集2019/01/30 06:04
stdio

総合スコア3307

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

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

apeirogon0813

2019/01/30 06:19

これはつまりNULLのnextを参照しようとしてエラーになっているのでしょうか?
stdio

2019/01/30 06:24

そうだと思います。 その上、 printf("%d->%d\n",adjlist[eki1],adjlist[eki1]->next); では、NULLの後のnextを参照しようとしているので、さらにエラーが出ていると思われます。
stdio

2019/01/30 06:25

そして、元のコードでは、 少し笑えますが、printf消したら治るな。
apeirogon0813

2019/01/30 06:36

おっしゃるとおりでした。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問