お世話になります、AEと申します。
次のような件に悩まされています。
○画像のラベリング処理において、再帰呼び出しによって塗りつぶし処理を行っているのですが、再帰の回数が多くなると途中でメモリリークによるものと思われるエラーが発生し処理が中断してしまいます。
#ただし、物理メモリを全部使い果たした様子はありません。
ソースコードやエラーメッセージを添付できず、漠然とした質問で大変心苦しいのですが、一般論として、
○Windows上で開発したプログラムにおいては、再帰の回数(あるいは再帰呼び出しのために確保されるメモリ量)は有限なのでしょうか?また有限であったとしてそれを拡張する設定があるのでしょうか?
ということについてご意見などいただければと思います。
****
無論、プログラム自体の不具合によってメモリリークを引き起こしているんじゃないの?とか、そもそもメモリが足りてないんじゃないの?というご意見もあるかと思いますが、それは取り敢えずおいておいて、一般的な意見として、「メモリの許す限り何回でもいけるぞ!」とか「同じような経験をしたぞ!」とかいう意見を伺えれば幸甚です。
合わせて解決策がもしあるものでしたらご意見ください。
一般的なUNIXではlimitでユーザが使えるメモリ量を設定できると思うのですが、そういう類の設定がWindowsにもあるぞ!というご意見などもお待ちしております。
勉強不足で申し訳なのですが、よろしくお願いいします。
No.2ベストアンサー
- 回答日時:
再帰の回数は有限です。
というより、再帰のために使えるメモリの量が有限です。数年前ためしたところでは、単純な級数の再帰で、
1万回程度の再帰呼び出しが限界でした。
この現象は、C言語のプログラムが使うメモリが、いくつかに
分かれていることに原因があります。
(メモリとしては同じなのですが、使われ方が違うのです。)
だいたい、4種類になります。
(1)コード領域(プログラムを記憶しておく)
(2)静的記憶領域(即値データを記憶しておく)
(3)スタック領域
(4)ヒープ領域
関数の再帰呼び出しのとき使うメモリは、(3)の「スタック領域」です。
一方、malloc()などで確保できるメモリは、(4)の「ヒープ領域」です。
一般的に、ヒープ領域の方がはるかに多くのメモリを確保できます。
スタック領域に使えるメモリは、それほど多くはありません。
そのかわり、関数呼び出しなどに使いやすい構造になっています。
スタックのメモリは、あくまでも「一時置き」と考えられています。
(これでもずいぶん多くなったのです。
MS-DOSの時代は、ちょっと深い再帰呼び出しをすると
すぐにスタックメモリが足りなくなりました)
スタックの量を増やすコンパイルオプションは、
コンパイラによって存在したと思いますが、
すみませんが覚えていません。
極端に増やすことはできないと思います。
どのみち限界があるので、
あまり深い再帰呼び出しはしない方がいいです。
(環境によって、どの程度なら大丈夫というのはありますが)
実用プログラムであれば、面倒でも、再帰を使わない構造に書き直す方がいいのではないでしょうか。
詳細な説明、ありがとうございました。
大変、ヒントになりました。
プログラミング自体は長年やっているのですが、この辺りの知識が乏しく情けないかぎりです。
結果としては再帰を使わない構造で書き直しておりますので、実用上問題ない状況にしてはいるのですが、以前から気になっていたものですので。
本当にありがとうございます。
No.4
- 回答日時:
これにはそもそもプログラムがどのように動作しているのかを理解する必要がある。
誤解を恐れずに言うと、1プログラムが使用するメモリには4種類ある。どれも物理的にはメモリに違いないのだが。
・コード:プログラムが置かれる
・データ:C言語だと、関数外で定義した変数などが置かれる
・ヒープ:C言語だと、malloc、MemoryAllocで確保したもの
・スタック:関数呼び出し履歴、関数内で定義した変数(実体はヒープに置かれる事もある)
イメージとして、4LDKを考えてください。コードの部屋、データの部屋、ヒープの部屋、スタックの部屋。ここで、君の症状の場合、スタックの部屋が満杯になっているのではないかと思う。4LDKなので、スタック君の部屋が手狭になったからと言って、壁をぶち抜いて他の部屋にスタック君の持ち物を置く訳にはいかない。
これをスタックオーバーフローと言い、関数呼び出し履歴が多すぎてスタック部屋が満杯になった状態だ。
スタックサイズを変更する事、その関数の引数や関数内変数を減らす事で、ある程度は対応できると思うが、根本的にはやはり色の塗り替えを部分的に分けるなどの対処が必要でしょうな。
ご回答ありがとうございます。
まさしく、メモリの取り扱いについての意識が低かったと反省というか甘さを感じております。
改めて、この辺りを勉強しなおそうと考えているところです。
参考になりました。
No.3
- 回答日時:
再帰関数の処理で制限になるのは、メモリというよりスタックとして確保されているメモリのサイズです。
スタックサイズを必要なだけ拡大するか、
あるいは、プログラムの中で使う変数をスタックではなくヒープで確保管理して再帰処理できるようにするかすればいいでしょう
修正のヒント、ありがとうございます。
やはり皆さんのおっしゃるようにスタック領域のサイズによるものと思います。
実のところ、ボリュームデータ(画像を立体に積み上げたようなデータ)を取り扱う処理をしておりまして、その内部のラベリングであるとか抽出であるとかそういう処理を行っております。ですので、皆さんが懸念しておられたようなとてつもなく深く再帰呼び出しされていることは疑いありません。
#これは認識していましたが、物理メモリの量でのみ考えていたところに落とし穴があったと。
つまり結論として通常のヒープ領域ではなくスタック領域がオーバーフローしていたということかと考えております。
今回の皆さんのご回答を下にこれらのメモリの扱い方を改めて勉強したいと思います。
ありがとうございました。
No.1
- 回答日時:
C言語においては再帰呼出しはスタックを消費します。
従って、スタックサイズの制限値が再帰段数の制限になりますが、16bit時代はともかく32bitモデルではスタックは通常は十分に大きいです。
従って、再帰呼出しされる関数で巨大な配列を自動変数で宣言しているとかでない限り簡単には制限には掛かりません。
なお、マルチスレッドの場合は初期スレッド以外はスタックサイズが小さい場合もあるので要確認です。
またコンパイラの設定でスタックサイズを指定している場合もありますのでこれも確認ください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(パソコン・周辺機器) Windowsマシン。USBタップの「自動切れ、再接続」がうざい。解決策は? 7 2023/01/25 08:27
- CPU・メモリ・マザーボード 質問お願いします 「「RAM2GB+拡張4GB」などと書いてあるのは、搭載されているメモリ(RAM) 6 2023/08/28 12:31
- ノートパソコン 理系大学生向けおすすめパソコン 8 2023/01/01 20:07
- 会社・職場 メンタル不調者からのいじめ嫌がらせをどう改善したらよいか 6 2022/04/10 21:37
- ノートパソコン Windows 10 動作改善方法 6 2023/04/26 22:30
- 美術・アート オリキャラ見てください&設定付けで困ってます②(再掲) ※色々不手際があったのと結構早めに過疎っちゃ 2 2023/02/22 16:11
- CPU・メモリ・マザーボード ゲーミングpcのファンのことについて教えて欲しいです。 6 2023/03/05 07:44
- その他(学校・勉強) この中で間違ってある説明はありますか?詳しい方に教えていただきたいです。 A. 1つのプログラムが複 2 2023/07/14 01:15
- CPU・メモリ・マザーボード Windows10 64bitパソコンのメモリ 4GBから8GBへ増設 11 2023/01/25 18:20
- その他(悩み相談・人生相談) 分譲マンションの役員メンバートラブルで精神不安定です。 3 2023/01/28 22:54
このQ&Aを見た人はこんなQ&Aも見ています
-
見学に行くとしたら【天国】と【地獄】どっち?
みなさんは、一度だけ見学に行けるとしたら【天国】と【地獄】どちらに行きたいですか? 理由も聞きたいです。
-
ちょっと先の未来クイズ第6問
2025年1月2日と1月3日に行われる、第101回箱根駅伝(東京箱根間往復大学駅伝競走)で、上位3位に入賞するチームはどこでしょう?
-
自分独自の健康法はある?
こうしていると調子がいい!みたいな自分独自の健康法、こだわりはありますか?
-
AIツールの活用方法を教えて
みなさんは普段どのような場面でAIツール(ChatGPTなど)を活用していますか?
-
今から楽しみな予定はありますか?
いよいよ2025年が始まりました。皆さんには、今から楽しみにしている予定はありますか?
-
C言語 配列の長さの上限
C言語・C++・C#
-
再起呼び出しの回数をカウントするプログラム
C言語・C++・C#
-
MFC ダイアログ上のID取得について
C言語・C++・C#
-
-
4
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ファイル...
おすすめ情報