teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

4

tuiki

2019/01/30 05:50

投稿

apeirogon0813
apeirogon0813

スコア117

title CHANGED
File without changes
body CHANGED
@@ -18,6 +18,9 @@
18
18
 
19
19
  いつもはこの様な方法でもおそらくNULLがそのまま代入されてセグメントエラーになってなかったと思うのですが
20
20
  今回のプログラムではセグメントエラーになってしまいました。
21
+
22
+ 関数dijkstraの局所局所にprint文を入れてどこでエラーなるかチェックしたところ
23
+ adjlist[cur] = adjlist[cur]->next;の手前まで出力されていたためこれが原因かと思っていました。。
21
24
  ```C
22
25
  #include<stdio.h>
23
26
  #include<stdlib.h>

3

tuiki

2019/01/30 05:50

投稿

apeirogon0813
apeirogon0813

スコア117

title CHANGED
File without changes
body CHANGED
@@ -86,20 +86,23 @@
86
86
  }
87
87
  cur = eki1;
88
88
  init_set(&unknown, ekisu, cur);
89
+ //セグメントエラー確認のためここでリストを巡回させるとやはりエラーになった//////////////////////
89
- while(adjlist[eki1]->next != NULL) {
90
+ while(adjlist[eki1] != NULL) {
90
91
  adjlist[eki1] = adjlist[eki1]->next;
91
92
  printf("%d->%d\n",adjlist[eki1],adjlist[eki1]->next);
92
93
  }
93
-
94
+ ////////////////////////////////////////////////////////////////
95
+
96
+
94
97
  while(unknown.size !=0 || cur != eki2) {
95
- while(adjlist[cur]->next != NULL) {
98
+ while(adjlist[cur] != NULL) {
96
99
  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]);
97
100
  if(dist[cur] + adjlist[cur]->kyori < dist[adjlist[cur]->eki])
98
101
  dist[adjlist[cur]->eki] = dist[cur] + adjlist[cur]->kyori;
99
102
  printf("next\n");
100
103
  printf("eki = %d, next = %d\n", adjlist[cur]->eki, adjlist[cur]->next->eki);
101
104
  printf("%d\n",adjlist[cur]->next);
102
- adjlist[cur] = adjlist[cur]->next;
105
+ adjlist[cur] = adjlist[cur]->next; //この前までのprintは出力された
103
106
  printf("eki = %d, next = %d\n", adjlist[cur]->eki, adjlist[cur]->next->eki);
104
107
  }
105
108
  printf("srgsrgs\n");

2

tuiki

2019/01/30 05:48

投稿

apeirogon0813
apeirogon0813

スコア117

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

1

追記

2019/01/30 05:45

投稿

apeirogon0813
apeirogon0813

スコア117

title CHANGED
File without changes
body CHANGED
@@ -14,4 +14,7 @@
14
14
  p->element = 2のとき
15
15
  p = p->next;
16
16
  とするとセグメントエラーになってしまいました。
17
- これはNULLを参照してしまったからでしょうか?
17
+ これはNULLを参照してしまったからでしょうか?
18
+
19
+ いつもはこの様な方法でもおそらくNULLがそのまま代入されてセグメントエラーになってなかったと思うのですが
20
+ 今回のプログラムではセグメントエラーになってしまいました。