エラー – プログラミング – Home

通知
すべてクリア

[解決済] エラー


まき
 まき
(@まき)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

プログラムがいきなり実行できなくなりました。
(ボタンをクリックすると次の例外がでます)
ボタンをクリックすると動作するプログラムです。
原因を教えてください。お願いします。

例外:
例外 unknown software exception (0xc00000fd)がアプリケーションの
0x0040e707で発生しました。
msgbox:
ハンドルされていない例外は ~.exeにあります:0XC00000FD:Stack Overflow。
デバッカの場所:
test dword ptr [ecx],eax ; ...probe it

環境はvc++6.0 MFC win2000sever です。


引用未解決
トピックタグ
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

Win32の環境でスタックオーバーフローとはまた豪快なプログラムですね。
関数内のローカル変数でとんでもない大きさのメモリを使ったりしていませんか?
あと、考えられるのは再起呼び出ししていてスタックを使い切っちゃったとか。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

追記

ローカル(オート)変数とか、グローバル変数とか(変数のスコープがらみ)の話を
C言語かC++言語の入門書(VC++でないところがみそ)で勉強された方が良いと思います。
この辺の話は結構基本的なところなので基礎知識をきちんと持っていないと話が通じない
可能性があるので。


返信引用
まき
 まき
(@まき)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

各関数内で大きなメモリを使ってました。
ローカルは関数内、グローバルはどの関数からも参照できるものですよね?
グローバルで宣言をして(値は入れていない)、関数内で宣言せずに
どの関数でもグローバルで宣言した変数を使用することは可能ですか?


返信引用
tib
 tib
(@tib)
ゲスト
結合: 24年前
投稿: 468
 

> グローバルで宣言をして(値は入れていない)、関数内で宣言せずに
> どの関数でもグローバルで宣言した変数を使用することは可能ですか?
もちろん可能です。が、よほどそうしなければならない正当な理由がない限り、勧めませ
ん。メモリの基本は「必要なときに必要なだけ使う」です。

> 各関数内で大きなメモリを使ってました。
各関数内で大きな「static領域」を使っていました、ならば問題ですが、そうでないのな
らあまり気にする事はありません。関数内で宣言されたメモリ領域は、その関数が生きて
いる間しか実際には使われないからです。

というわけで、
・staticでメモリを確保していないか
・必要以上にとてつもなく大きな領域を確保していないか
あたりをチェックしてみてください。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

あらら、グローバル変数でそういう質問が出てしまうと言う事は、
その辺の基礎知識が無いって事になりますけれど。
グローバル変数は、関数内で宣言しないからグローバルなんですけれどね。
関数外のグローバル領域で宣言した変数は同一モジュール内であれば、
自由に参照可能です。
モジュールが違う場合は、グローバルの変数が宣言されていない方のモジュールで
extern宣言をする必要が有ります。
この話は特別な話ではなくて普通の入門書に書いてある話です。
但し、VC++の入門書では文法に関しては説明を省いていある場合が多いので
C言語やC++言語の勉強には役に立ちません。C言語かC++言語の入門書を用意した方が
いいです。実験的にプログラムするのであれば、MFCを使う必要も有りません。
いっその事、コンソールプログラムで勉強した方が良いくらいです。

あと、ローカルに変数を作るのではなくて、
ローカルではポインタで宣言しておいてヒープ領域にメモリを確保して使用する事でも
解決可能だと思います。
但し、この場合は、メモリの確保と解放を意識したプログラミングをしないと
メモリリークしますので注意が必要です。

とにかく、C言語かC++言語の入門書を読んでこの辺の文法に関する基礎知識を収集して
ください。このレベルの話をこういった掲示板で延々としても掲示板としてのデータ
ベース的な役割はあまり満たされません。
この手の技術的な掲示板の目的の一つに手に入りやすい本や容易にWebで見つからない
ような技術的な情報の蓄積が有ります。
手に入りやすい本で解決可能な部分はなるべく自分で本を買って自己解決できるように
頑張ってください。
質問するなと言う意味では有りません、自己解決の努力の跡を見せてほしいと思います。
そうしないとあなたの質問にレスをつける人がだんだん減ってくるかもしれません。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

static領域であれば、スタック上に取られる事は無いはずなので
問題ないと思いますよ。出てきているエラーがスタック・オーバーフローですし。
それとも私の勘違い??

むしろ、staticをつけずにローカルで大きな変数を宣言する事に問題があるはずです。
大きなサイズのバッファが必要であれば、グローバルに確保するか、
ローカルにポインタを取っておいて、newとかmallocとかLocalAllocとかでメモリを
確保するのが一般的な解決法だと思います。

ただ、質問ではどーしてこんなエラーが出るのでしょうかと言う話だったので
ローカル変数で大きなサイズの変数を宣言したりしていないかと聞いたのです。

ローカル変数はプログラム上はスタック領域と言うところに確保されます。
スタック領域はPCの搭載メモリとは直接関係しません。
リンク時の/STACKオプションで指定します。
Win32の環境であれば、多分1MBぐらいだったと思います。
ですから、非常に大きなメモリをここで宣言してしまうとスタック領域が足りなく
なります。これがスタック・オーバーフローです。
スタックに関する詳しい説明を始めると関数呼び出しがどうと言うところまで
突入するので詳しくは本を読んで自分で勉強してください。


返信引用
tib
 tib
(@tib)
ゲスト
結合: 24年前
投稿: 468
 

> static領域であれば、スタック上に取られる事は無いはずなので
そうでした。失礼。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

追記。

>各関数内で大きな「static領域」を使っていました、ならば問題ですが、
>そうでないのならあまり気にする事はありません。
>関数内で宣言されたメモリ領域は、その関数が生きている間しか実際には
>使われないからです。

これについてはこれだけでは説明不足だと思いますよ。
関数には呼び出し元が有りますが、この呼び出し元もやはり関数ですよね。
C言語だと最初に記述するのはmain関数ですが、これもまたそのなの通り関数です。
関数内で宣言されたローカル関数は確かに関数の寿命と同じですが、
例えば、main関数で大きなローカル変数を宣言してしまった場合、
main関数の終了までそのローカル変数は保持されますから、
結局、そのプログラムが終わるまで解放されないことになります。
既に書いている通り、スタック領域はヒープ領域などに比べて小さいので
呼び出される関数ごとに大きなメモリを宣言したり、するとスタック領域が足りなくなり
ます。
ローカル関数は確かに関数の寿命にあわせて解放される便利な変数ですが、
関数の呼び出し深度まで考慮入れてきちんと設計されていないかぎりローカル変数に
大きなサイズの変数を宣言すべきではないと思います。
このサイズをどの程度にするかはある程度設計側の裁量に任されますが、
数百キロもあるような変数をどしどし関数内で宣言するのはどうかと思います。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

がーん。誤字。

誤)
>関数内で宣言されたローカル関数は確かに関数の寿命と同じですが、

正)
 関数内で宣言されたローカル変数は確かに関数の寿命と同じですが、

誤)
>ローカル関数は確かに関数の寿命にあわせて解放される便利な変数ですが、

正)
 ローカル変数は確かに関数の寿命にあわせて解放される便利な変数ですが、

でした。


返信引用
まき
 まき
(@まき)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

解決いたしました。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

質問した以上は、どこに問題があってどう修正したのかを報告してスレッドを
終了させてください。そうしないと掲示板の意味がない。

掲示板は後から他の人が同じ問題にぶち当たった時に参照されるものです。
最後に結果の報告をきちんとしないと後から見る人の役に立ちません。

掲示板は無料で質問できる場ではなく、こうした問題とその解決方法を蓄積して
他の人が利用できるデータベースを作成する事に有ります。
結果として質問者が解決策を得られる事もありますが、
得られない場合も有ります。
掲示板が共有の場である事を理解して利用するのが筋だと私は思います。

まきさんに限らず、質問者全般に言えることですけれど。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました