ページ 11

再帰的処理の強制停止

Posted: 2011年12月13日(火) 15:17
by あんどれ
こんにちは。プログラミング初心者です。

C言語で再帰的処理を用いたプログラムを作製したのですが、デバッグを行うと処理が完了する前に強制終了されてしまいます。

原因をネットで調べたところ「ポインタと再帰処理の組み合わされたプログラムを実行すると強制終了する事がある。」
といった文をみつけましたが、具体的な事が書かれていませんでした。

この文が本当ならば、
私の作成したプログラムもメイン関数で宣言した変数を再帰処理中にポインタで参照しているため、おそらくこの事が強制停止の原因と見ています。

そこで質問なのですが、なぜポインタと再帰処理の組み合わせで強制終了されるのでしょうか?

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 15:22
by beatle
ポインタと再帰関数を組み合わせると必ずダメになるというのではなくて、ポインタと再帰関数が両方共難しい機能であるがためにバグが出やすいということだと思います。注意深く作れば、再帰関数でポインタを使っても問題なく動くはずです。
具体的なソースコードを示していただければ、どこが悪いのかは指摘できると思います。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 16:22
by softya(ソフト屋)
再帰ですと過剰再帰のスタックオーバーフローの危険性も高いです。
停止したときに出たエラーメッセージも分かると原因の解明に役立ちます。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 16:43
by あんどれ
早速の回答ありがとうございます。
数千回の再帰的処理が行われている最中に毎回ほぼ同じ回数で停止してしまいます。

注意深く考えれば問題なく動くと言う事なのでもう少し自力で考えてみたいと思います。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 16:48
by あんどれ
ページ更新忘れてました。
softya(ソフト屋) さんが書きました:再帰ですと過剰再帰のスタックオーバーフローの危険性も高いです。
私自身これを疑っているのですがこれを防ぐ方法が分かりません。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 16:51
by softya(ソフト屋)
あんどれ さんが書きました:早速の回答ありがとうございます。
数千回の再帰的処理が行われている最中に毎回ほぼ同じ回数で停止してしまいます。
注意深く考えれば問題なく動くと言う事なのでもう少し自力で考えてみたいと思います。
数千回が呼び出しネストの深さならスタックオーバーフローの可能性が高いですね。
あんどれ さんが書きました:私自身これを疑っているのですがこれを防ぐ方法が分かりません。
アルゴリズムを変えるかスタックサイズを増やすぐらいしか手はありません。
スタックサイズの増やし方はOS・開発環境・コンパイラによって変わります。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 19:48
by あんどれ
再帰を行ったり来たりしている処理で、その合計回数が数千回で止まる時の深さで言えば40程度でした。
いろいろと至らないところがありすみません。。。

環境は以下です。
OS: windows vista home premium 32ビット
環境: visual C++ 2008 無料版
コンパイラ: Microsoft C/C++ Compiler

ちなみに停止した時のメッセージはこうなっています。
「ファイル名.exe は動作を停止しました」 
「問題が発生したため、プログラムが正しく動作しなくなりました。プログラムは閉じられ、解決策がある場合はwindowsから通知されます。」

またあまり関係ないかもしれませんが、
大域でstruct STR{ int array[9][9][9] }S[80];
のように宣言した3次元配列により深い処理に入るたび情報を記憶させてます。
再帰の最大深さは81になるはずです。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 20:05
by bitter_fox
あんどれ さんが書きました:再帰を行ったり来たりしている処理で、その合計回数が数千回で止まる時の深さで言えば40程度でした。

またあまり関係ないかもしれませんが、
大域でstruct STR{ int array[9][9][9] }S[80];
のように宣言した3次元配列により深い処理に入るたび情報を記憶させてます。
再帰の最大深さは81になるはずです。
ソースコードを提示してください。

深さが81の時はSの何番目の要素にアクセスしてるんでしょう?
S[79]までしかアクセスしてはいけませんよ。

Re: 再帰的処理の強制停止

Posted: 2011年12月13日(火) 23:39
by あんどれ
bitter_fox さんが書きました:深さが81の時はSの何番目の要素にアクセスしてるんでしょう?
強制終了により深さ81まで到達出来てないですが81番目では記憶させる必要が無いのでS[80]としています。

またスタックサイズについても調べて、増やしてみたところ実行結果に影響は無かったため、アルゴリズムそのものを見直しているところです。

再帰的処理でも
注意深く作れば再帰関数でポインタを使っても問題なく動くと言う事、
再帰処理時のスタックオーバーフローの危険性
という答えが得られたので今回はひとまず解決とします。

回答してくださった方々には
コードも貼らずにまどろっこしい思いをさせてしまったかと思いますが、ありがとうございました。またよろしくお願いします。