以下のサイトでC言語の勉強をしているのですが、このサイトのソースコードをコピペして実行してみたら上手くいきませんでした。
http://wisdom.sakura.ne.jp/programming/c/c30.html
==========================
#include<stdio.h>
void func(int );
int main() {
func(0);
printf("プログラムを終了します");
return 0;
}
void func(int max) {
if (max <= 10000) {
printf("%d\r",max);
func(max + 1);
}
}
==========================
実行してみると、何故か4700~4800の辺りで止まってエラーになってしまいます。
どうしてエラーになるのでしょうか?
No.4ベストアンサー
- 回答日時:
一言で言えば「スタックが溢れた」と思われます。
一般的に、C言語プログラムの関数呼び出しは、次のような処理によって実現されます。
(1)次のようなデータを、「スタック」と呼ばれるメモリ領域に保存
・呼び出し先の関数の処理が完了した後に、戻ってくるべき場所(アドレス、といいます)
・呼び出し先の関数に渡す引数値(この例では、maxなどが、それに相当)
(2)呼び出し先の関数の中で新たに変数などを使う場合は、そのための領域をスタックに追加確保(今回の例では、これはありませんが)
(3)呼び出し先の関数の処理を実行
(4)関数の処理が終わったら、(1)(2)で確保したスタックのメモリ領域を解放して、(1)で保存された場所に処理を戻す
(正確には他にもありますが、割愛します)
今回の例では、再帰呼び出しが行われているので(4)まで終わる前に、新たに(1)からの処理が追加で行われ、再帰が深くなるにつれて、次第にスタックが消費されて行きます。
スタックが無尽蔵にあれば、再帰が10001段(で、あってるかな)になるまで(1)から(3)が繰り返され、最終的に今度は関数の再帰処理が一段ずつ終了していくため、(4)が繰り返されます。
ところが、再帰が深くなっていく途中でスタックが尽きてしまうと、そこでスタックメモリ領域が溢れてしまい、そこから先が正常に動作を続けられなくなってしまいます。
スタックメモリがどの程度確保されるかは、環境によりけりで、ソースコードをコンパイルする際のオプション等で指定できる場合もありますが、いずれにしても、10000段もの再帰をするようなプログラムは、こういった実行環境の特性を踏まえていない、不適切な再帰の使い方だと思います。
このように、極端に深い再帰を何も考えずにするようなプログラミングは、悪い見本なので、真似をしないことをおすすめします。
関数の再帰的処理ってスタックを用いてたのですね。
再帰的処理にそのような問題があったとは驚きです。
こういう処理はなるべく避けるように気を付けたいと思います。
回答ありがとうございました。
No.6
- 回答日時:
スタックオーバーフローだと思うけど、printf関数の呼び過ぎで引っ掛かっている可能性もあるね。
まずはosにもよるけどprintf("%d\r",max);の¥rを¥nで実行してみてね。
ダメなら次はprintfを移動させてみてね。
void func(int max) {
if (max <= 10000) {
func(max + 1);
printf("%d\r",max);
}
}
10000まで実行してから帰りに減算しながら数値表示になるよ。
10000の表示まで行ったらスタックはokかも。
No.5
- 回答日時:
追記:
>このように、極端に深い再帰を何も考えずにするようなプログラミングは、悪い見本なので、真似をしないことをおすすめします。
十分なスタックを確保できることが事前にわかっていて、深い再帰をするアルゴリズムに必然性があるなど、十分に考慮した上での場合は、(「何も考えずに」ではないですし)この限りではありません。
補足ありがとうございました。
深い再帰をする必要のある状況があるかどうかは分かりませんが、再帰的処理の問題点は頭の片隅に入れておきます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# Cのオブジェクトファイルの逆アセンブル 5 2023/05/13 01:51
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# プログラミングペーパーテスト 次の問題の実行結果を答えろ #include int x[ ] = { 1 2022/06/16 21:49
- C言語・C++・C# プログラミングを教えて欲しいです。 配列aは、int a[9]={7,6,12,8,3,5,10,9 4 2022/12/19 23:27
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# プログラミングの授業のペーパーテスト 実行結果を答えろ #include int x[ ] = {1 3 2022/06/16 20:08
このQ&Aを見た人はこんなQ&Aも見ています
-
それもChatGPT!?と驚いた使用方法を教えてください
仕事やプライベートでも利用が浸透してきたChatGPTですが、こんなときに使うの!!?とびっくりしたり、これは画期的な有効活用だ!とうなった事例があれば教えてください!
-
【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
【お題】・忍者がやってるYouTubeが炎上してしまった理由
-
最強の防寒、あったか術を教えてください!
とっても寒がりなのですが、冬に皆さんがされている最強の防寒、あったか術が知りたいです!
-
【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
「出身中学と出身高校が混ざったような校舎にいる夢を見る」「まぶたがピクピクしてるので鏡で確認しようとしたらピクピクが止まってしまう」など、 これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
-
【選手権お題その2】この漫画の2コマ目を考えてください
サッカーのワンシーンを切り取った1コマ目。果たして2コマ目にはどんな展開になるのか教えてください。
-
C言語における再帰呼び出しの限界?について
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【選手権お題その3】この画像で一言【大喜利】
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・ちょっと先の未来クイズ第6問
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語で、メモリを解放しないで...
-
VBAの配列サイズとメモリに関して
-
CImage::ReleaseDC()のエラーで...
-
メモリ不足
-
C#におけるexeファイルのサイズ...
-
メモリが不足しています(VBA)
-
シェル(perl)が使用するメモリ...
-
C言語における再帰呼び出しの...
-
C#のOutOfMemoryException発生...
-
エクセルVBA 大容量CSVファイル...
-
「memcpy」と「strcpy」について
-
C,C++プログラムの強制終了時の...
-
VB.netでUSBメモリの固有I...
-
ファイルマッピング関数で失敗
-
これて逆じゃないですか?
-
プログラム領域の算出方法
-
メモリのセグメント違反の解決...
-
使わなくなった変数に違う値を...
-
Apacheでバーチャルホストの最...
-
直接メモリにアドレス割付けで...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
メモリのセグメント違反の解決...
-
「memcpy」と「strcpy」について
-
「ヒープサイズの設定」て何?
-
C言語における再帰呼び出しの...
-
メモリが不足しています(VBA)
-
【C言語】再帰が時間がかかる...
-
エクセルのメモリ使用状況/Appl...
-
大容量のメモリ確保をスワップ...
-
C#のOutOfMemoryException発生...
-
メモリ不足
-
ファイルマッピング関数で失敗
-
C++のCopyFileでメモリが増える
-
C言語初心者です。debug assert...
-
C言語:関数のメモリ上でのサイ...
-
移動可能メモリ
-
EXCEL-VBAにてADOのレコードセ...
-
VB.netでUSBメモリの固有I...
-
エクセルVBA 大容量CSVファイル...
おすすめ情報