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

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

ただいまの
回答率

88.64%

セグメントエラーで実行されません

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,174

tsuji

score 7

ソースコードを分割してコンパイルする課題を行っています。そこでコンパイルしたファイルを実行しようとしてもセグメントエラーが表示されてしまいます。誤りを自分でも探してみたのですがどうしても見つかりません。よろしければ原因を教えてもらえないでしょうか。よろしくおねがいします。

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

”xの値を入力 >” までの処理しか行われない。

該当のソースコード


mylib.h

double fctrl(int);
double taylor(double,int);

ex2-2

#include<stdio.h>
#include<math.h>
#include"mylib.h"

int main(void){
  double x,err;
  int n;

  printf("xの値を入力  >");
  scanf("%lf",&x);

  err=1;
  for(n=0;err>=0.005;n++){
    err = fabs(exp(x)-taylor(x,n));
  }
  printf("第%d項まで展開する必要がある\n",n);
  return 0;
}


fctrl.c

double fctrl(int n){
  if(n==0){
    return 1;
  }else{
    return n*fctrl(n-1);
  }
}


taylor.c

#include<math.h>
double taylor(double x, int n){
  if(n==0){
    return 1;
  }else{
    return pow(x,n)/fctrl(n)+taylor(x,n-1);
  }
}

試したこと

ex2-2がどこまで処理されているのか確かめたところscanfのあたりから処理されていないところまでわかりました。

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

コンパイルはgcc -o ex13 mylib.h ex2-2.c fctrl.c taylor.c -lm  の形で行いました。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • mit0223

    2017/01/28 12:08

    言語はC言語ですよね。C#になっているので、修正してもらえますか。

    キャンセル

回答 2

checkベストアンサー

+1

こんにちは。

xに小さな値を入れれば計算終了します。
35までは終了し、36は終了しませんでした。
taylor展開計算の中で何かオーバーフローが発生しているようです。
指数関数の増え方は爆発的ですから、意外に簡単にオーバーフローします。

ちなみに下記の文をループの中に入れることで解りました。

printf("[%d] err=%f exp(x)=%f taylor(x,n)=%f\n", n, err, exp(x), taylor(x,n));


【追記】
fctrl(n)のところで警告がでてましたのでtaylor.cに#include"mylib.h"を補なってます。
この#include無しの場合、コンパイラはint fctrl(int n)と解釈している筈なので、そこで落ちたのかも知れません。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/01/28 12:48

    回答ありがとうございます!
    fctrl(n)のところを完全に見落としていました。おかげで無事実行することができました。本当にありがとうございます!

    キャンセル

0

根本原因はプロトタイプ宣言をせずに関数を呼び出すコードを書いているためだと思います。
対処はtaylor.cの先頭に#include "mylib.h"を追加することです。

コンパイラーが「宣言なしに関数を呼び出している」という警告を発しているはずですがそれを無視してしまったのですね。

fctrlという階乗を計算する関数をtaylor.cでプロトタイプ宣言なしに呼び出しています。C言語ではこういう関数呼び出しを書いてしまうと「戻り値の型をintと仮定」してコンパイルしてしまいますがプログラムのバグの可能性があるととらえてコンパイラーがその旨の警告を発します。

典型的なPCの環境ではintは32bit, doubleは64bit(IEEE形式)になると思いますが、taylor.cのコンパイル時にfcntlの戻り値が「intである」という間違った仮定でネイティブコードが生成されると、fctrlが本来返しているdouble型の値とは全然違う値をtaylor関数で受け取ってしまい、その値に基づいて計算した結果おかしな値になってしまったのでしょう。

ご質問のコードではテイラー展開の計算を再帰的アルゴリズムで行っています。計算誤差が一定以上の間、テイラー展開式の項数を増やしながら誤差が減っていくことを期待したプログラムなのですが前述のバグによって値が収束しないため項数nがどんどん巨大になってしまいある時点でスタックオーバーフローを起こしsegmentation violationが発生したのだと思います。


訂正:
上の回答間違ってました。
fctrlは標準ライブラリーのfctrlの方がが呼ばれちゃったんですね・・・標準ライブラリーの方のfctrlが正しくない引数で呼び出されたために異常終了したんだと思います。
できるだけ標準ライブラリーに存在する関数名を使わないように注意できるといいかも知れませんね。例えば階乗はfactorialにしておくとか。(factorialもあったりして・・・)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/01/28 13:30

    回答ありがとうございます!
    警告は「fctrlがビジー状態です」と表示されたのですが、よく意味がわからずコンパイルもされるため軽視していました…。詳しく説明もしていただきありがとうございます!

    キャンセル

  • 2017/01/28 14:01

    あ・・・標準ライブラリーのfctrl(ファイルの制御をするための関数)が呼ばれたんですね。上の回答は間違いでした(w;)

    キャンセル

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

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

関連した質問

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