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

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

ただいまの
回答率

89.13%

Segmentation faultについて

受付中

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 572

fairylion

score 12

前提・実現したいこと

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

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

Segmentation fault (core dumped)

該当のソースコード

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LIMIT_LOW 0
#define LIMIT_HIGH 25

/* 構造体の定義 */
typedef struct tag {
  int temp;   /* 温度 */
  struct tag *next; /* 自分自身の型へのポインタ変数 */
} tempData;       /* 温度データ */


/* 新データ作成関数 */
tempData* makeNewNode(int t) {
  tempData* pNewNode;
  /*** person 型のメモリ領域確保 ***/
  pNewNode = (tempData*)malloc(sizeof(tempData));
  if (pNewNode != NULL) {
    /*** データ設定 ***/
    pNewNode->temp= t;
    pNewNode->next = NULL;
  }
  return pNewNode ;
}


int main(void) {
  int temp; /* 温度入力用変数 */
  tempData *pTop;  /* 温度データリストのトップ */
  tempData *pNow;  /* 温度データリスト内の現在位置 */
  tempData *pNew;  /* 温度データの新規データ */
  /* 必要であれば,ここに変数を追加 */
  int i = 1; /*データ数の計測用*/
  int ave = temp; /* 平均値の計算用 */

  /* 最初のデータは,必ず範囲内のデータであるとする */
  printf("温度を入力\n");
  scanf("%d", &temp);
  pTop = makeNewNode(temp);
  pNow = pTop;
  /* 次のデータを入力 */
  scanf("%d", &temp);

  while ( (LIMIT_LOW <= temp) && (temp <= LIMIT_HIGH)) {
    /* ここにリスト作成処理を記述 */
    pNew = makeNewNode(temp);
    pNow->next = pNew;
    pNow = pNew;

    ave = ave + temp;
    i = i + 1; /*データの数を計測*/

    /* 次のデータを入力 */
    scanf("%d", &temp);
  }


  /* ここに平均より大きいデータだけ表示する処理 */
  ave = ave / i ; /*平均値の導出*/


  tempData *pMae = NULL; /*温度データリスト内の現在位置の一つ前*/

  /*リストから平均値以下を削除*/
  pNow = pTop;
  while(pNow != NULL){
    if(pNow->temp < ave){
      pMae->next = pNow->next;


    }else{
      pMae = pNow;
    }
    pNow = pNow->next;
   }

  /*データ出力*/
  printf("--------\n");
  printf("実行結果\n");


  pNow = pTop;
  while (pNow != NULL){
    printf("%d\n", pNow->temp);
    pNow = pNow->next;
  }

  return 0 ;
}

試したこと

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

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

AWS cloud9

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

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

  tempData *pMae = NULL; /*温度データリスト内の現在位置の一つ前*/

  /*リストから平均値以下を削除*/
  pNow = pTop;
  while(pNow != NULL){
    if(pNow->temp < ave){
      pMae->next = pNow->next;  // ここが問題


    }else{
      pMae = pNow;
    }
    pNow = pNow->next;
   }

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

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


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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/10 23:11

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

    あと、int ave = 0; です。

    キャンセル

  • 2019/06/10 23:18

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

    キャンセル

0

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

    pNew = makeNewNode(temp);

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/10 23:11

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

    キャンセル

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る