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

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

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

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

Q&A

4回答

726閲覧

Segmentation faultについて

fairylion

総合スコア12

C

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

0グッド

0クリップ

投稿2019/06/10 13:49

前提・実現したいこと

温度を入力し、平均値以上の温度の場合出力を行うというプログラムを作成しているのですがSegmentation fault (core dumped)と表示され動作しません。Segmentation faultとは何なのでしょうか

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

Segmentation fault (core dumped)

該当のソースコード

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define LIMIT_LOW 0 6#define LIMIT_HIGH 25 7 8/* 構造体の定義 */ 9typedef struct tag { 10 int temp; /* 温度 */ 11 struct tag *next; /* 自分自身の型へのポインタ変数 */ 12} tempData; /* 温度データ */ 13 14 15/* 新データ作成関数 */ 16tempData* makeNewNode(int t) { 17 tempData* pNewNode; 18 /*** person 型のメモリ領域確保 ***/ 19 pNewNode = (tempData*)malloc(sizeof(tempData)); 20 if (pNewNode != NULL) { 21 /*** データ設定 ***/ 22 pNewNode->temp= t; 23 pNewNode->next = NULL; 24 } 25 return pNewNode ; 26} 27 28 29int main(void) { 30 int temp; /* 温度入力用変数 */ 31 tempData *pTop; /* 温度データリストのトップ */ 32 tempData *pNow; /* 温度データリスト内の現在位置 */ 33 tempData *pNew; /* 温度データの新規データ */ 34 /* 必要であれば,ここに変数を追加 */ 35 int i = 1; /*データ数の計測用*/ 36 int ave = temp; /* 平均値の計算用 */ 37 38 /* 最初のデータは,必ず範囲内のデータであるとする */ 39 printf("温度を入力\n"); 40 scanf("%d", &temp); 41 pTop = makeNewNode(temp); 42 pNow = pTop; 43 /* 次のデータを入力 */ 44 scanf("%d", &temp); 45 46 while ( (LIMIT_LOW <= temp) && (temp <= LIMIT_HIGH)) { 47 /* ここにリスト作成処理を記述 */ 48 pNew = makeNewNode(temp); 49 pNow->next = pNew; 50 pNow = pNew; 51 52 ave = ave + temp; 53 i = i + 1; /*データの数を計測*/ 54 55 /* 次のデータを入力 */ 56 scanf("%d", &temp); 57 } 58 59 60 /* ここに平均より大きいデータだけ表示する処理 */ 61 ave = ave / i ; /*平均値の導出*/ 62 63 64 tempData *pMae = NULL; /*温度データリスト内の現在位置の一つ前*/ 65 66 /*リストから平均値以下を削除*/ 67 pNow = pTop; 68 while(pNow != NULL){ 69 if(pNow->temp < ave){ 70 pMae->next = pNow->next; 71 72 73 }else{ 74 pMae = pNow; 75 } 76 pNow = pNow->next; 77 } 78 79 /*データ出力*/ 80 printf("--------\n"); 81 printf("実行結果\n"); 82 83 84 pNow = pTop; 85 while (pNow != NULL){ 86 printf("%d\n", pNow->temp); 87 pNow = pNow->next; 88 } 89 90 return 0 ; 91}

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

AWS cloud9

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

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

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

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

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

guest

回答4

0

問題が発生しているのは、下記の「ここが問題」とコメントを記した行と思われます。pMaeの値がNULLのままこの行に到達すると、アクセスできない領域への書き込みを行おうとすることになりますので、Segmentation faultが発生します。

c

1 tempData *pMae = NULL; /*温度データリスト内の現在位置の一つ前*/ 2 3 /*リストから平均値以下を削除*/ 4 pNow = pTop; 5 while(pNow != NULL){ 6 if(pNow->temp < ave){ 7 pMae->next = pNow->next; // ここが問題 8 9 10 }else{ 11 pMae = pNow; 12 } 13 pNow = pNow->next; 14 }

この行にはいきなり到達しないつもりで作ったつもりならば、それも問題でしょう。どうやらaveの計算処理に誤りがあるようです。

c

1 int temp; /* 温度入力用変数 */ 2 (中略) 3 int ave = temp; /* 平均値の計算用 */

のように宣言されていますが、これではaveは不定値になってしまうでしょう。int ave = 0;の誤りなのでは?

投稿2019/06/10 14:10

keicha_hrs

総合スコア6768

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

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

0

Segmentation faultとは、アクセス違反が起こったときに、運がよかったら表示されるメッセージです
運が悪かったら、なにも言わずに暴走するか、
もっと悪ければ何食わぬ顔して動き続けます。

#そして、数ヶ月して問題が出る

投稿2019/06/10 14:58

y_waiwai

総合スコア87749

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

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

0

原因かどうかは別にして・・・

pNew = makeNewNode(temp);

これって、NULLが帰ってきたらどうなります?

投稿2019/06/10 14:03

編集2019/06/10 14:07
cateye

総合スコア6851

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

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

cateye

2019/06/10 14:11

scanf()やmalloc()のライブラリが、常に成功すると思わないことです。必ずエラー判定をしましょう。
guest

0

Segmentation faultとは何なのでしょうか

メモリアクセスの失敗と言うことで、原因としては、
・ポインタ処理のバグ
・配列の添え字範囲外をアクセスしようとした
がほとんどでしょう。

投稿2019/06/10 13:55

otn

総合スコア84505

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

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

otn

2019/06/10 14:11

とりあえず、tempData *pMae = NULL; がSegmentation faultの直接原因だと思われるので、それを tempData *pMae = pTop; に変えればSegmentation faultにはなりませんが、先頭ノードの処理を間違えているので、このままでは駄目ですね。 あと、int ave = 0; です。
otn

2019/06/10 14:18

もし、 /* 最初のデータは,必ず範囲内のデータであるとする */ というのが、 /* 最初のデータは,必ず範囲内で、平均以上のデータであるとする */ ならば、先頭ノードの処理は、このままでいいかな。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問