• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:【C言語】再帰を用いるプログラムでのセグフォ)

C言語の再帰を用いるプログラムでのセグフォの対処方法

このQ&Aのポイント
  • C言語の再帰を用いるプログラムでセグメンテーションフォルト(segfault)が発生する場合、再帰の終了条件を確認してください。
  • 再帰が1度しか行われない場合は正常に動作するが、再帰が2度以上行われる場合にsegfaultが発生することがあります。
  • segfaultが発生する場合は、再帰関数の引数や処理の制御フローを見直し、正しい終了条件を設定してください。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.3

最大公約数はそもそもどうやって求めるか分かっていますか? それとも単純にタイプミスでしょうか? vx&vy ↓ vx%vy なお、return の返値全体を括弧で囲むのは、文法間違いではありませんが、普通はしません。 なので、 return vy == 0 ? vx : gcdf(vy, vx % vy) ;

mist55
質問者

お礼

ありがとうやで

mist55
質問者

補足

申し訳ありませんタイプミスです。 vx%vyとした上で 大きな数値(2桁以上)を入力すると すぐにセグフォが起こるのです。

すると、全ての回答が全文表示されます。

その他の回答 (5)

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.6

プリントしてセグフォを特定なのだ #include<stdio.h> int gcdf(int vx, int vy) { printf("gcdf vx %d vy %d\n",vx,vy); return (vy==0? vx: gcdf(vy, vx%vy)); } int gcd(int va, int vb) { printf("gcd va %d vb %d\n",va,vb); return (va>vb? gcdf(va, vb): gcdf(vb, va)); }

すると、全ての回答が全文表示されます。
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.5

>vx%vyとした上で大きな数値(2桁以上)を入力するとすぐにセグフォが起こるのです。 ということであれば、書かれている範囲のプログラムにおかしい部分はないので、 書かれていない範囲のプログラムが間違っていると思います。 よく見直して下さい。

mist55
質問者

お礼

ありがとうございました

すると、全ての回答が全文表示されます。
回答No.4

うーん、こちらだと特に問題ないんですけどねぇ。 Ubuntu 14.04LTSの64ビット、コンパイラは同じくclang使ってみましたが、2桁以上・・・まあ、このケースだと3桁でやってみましたが、セグフォは起きませんでした。 #include<stdio.h> // ソースは同じ int gcdf(int vx, int vy) { return (vy==0? vx: gcdf(vy, vx%vy)); } int gcd(int va, int vb) { return (va>vb? gcdf(va, vb): gcdf(vb, va)); } int main (void) { printf("%d\n", gcd(123, 456)); return 0; } // 実行 ➜ OKwave clang List8-7.c ➜ OKwave ./a.out 12 // ここまで まあ、「大きな数」ってのがどれくらい指すのか、って分からないと何とも言えないですけどねぇ。 もちろん、C言語なんかの場合、「int」が想定してる「最大の整数」を超えると挙動がおかしくなったりはするでしょう。 (Cの場合、最大の整数は32,767ですかね?) なお、このソースの場合、Lispなんかやってる人だと当たり前の知識なんですが、「末尾再帰」と言うテクニックで記述されています。 末尾再帰ってのは、再帰で関数を呼び出す場合、その呼び出された関数に「余計な操作を加えてない」って意味ですね。 int gcdf(int vx, int vy) { return (vy==0? vx: gcdf(vy, vx%vy)); <- 条件によって、returnで呼び出される関数はgcdf「だけ」で、他にgcdf自体には余計な操作を加えていない。 } さて、末尾再帰も再帰も原理的にはスタック(メモリ上の・・・簡単に言うと「関数呼び出し」の為の情報を保持しておく領域?)を消費して「効率が悪い」んですが、一方、末尾再帰の場合は、コンパイラの記述方法如何によっては「末尾再帰最適化」と言う技術が使われていて、末尾再帰で書かれたコードを単純なジャンプ構文に「自動変換」してくれて、スタックの消費を避けてくれます。 ありがたい事に、clangと言うコンパイラは末尾再帰最適化を行って、大変効率的なマシン語に落としてくれる模様です。 つまり、環境によるんですが、スタックを消費し過ぎた場合、セグメンテーションフォールトを起こす可能性がある、んですよねぇ。 clangで末尾再帰最適化を行う場合、コンパイル時点で -O3と言うオプショナル引数を与えます。 例えば、 clang -O3 自分で書いたソース のように、ですね。 一回、このように、問題のソースを末尾再帰最適化を指定してコンパイルしてみて試してみて下さい。

すると、全ての回答が全文表示されます。
回答No.2

int gcdf(int vx, int vy) { return(vy == 0? vx: gcdf(vy,vx&vy)); <- ココ } gcdfの第二引数で使われてる演算子が、&じゃなくって%にすべきなんじゃないですかね?

mist55
質問者

お礼

ありがとうやで

mist55
質問者

補足

申し訳ありませんタイプミスです。 vx%vyとした上で 大きな数値(2桁以上)を入力すると すぐにセグフォが起こるのです。

すると、全ての回答が全文表示されます。
  • Wap58
  • ベストアンサー率33% (29/87)
回答No.1

プリントすればわかります、無限ループになります。 わざと間違えて考えさせるソースなんでしょう

mist55
質問者

お礼

ありがとう

すると、全ての回答が全文表示されます。

関連するQ&A