アプリ版:「スタンプのみでお礼する」機能のリリースについて

C++で関数を再帰呼び出しするとスタックオーバーフローとなりました。
それで、どれ位なら可能か調べるため、次の関数で試してみました。

intnull(void)
{
 int a;
 return null();
}

結果は次の通りでした。
1回目 &a 0x001cf9d4
2回目 &a 0x001cf8f4
3回目 &a 0x001cf814

よって、一回の呼び出しでスタックをe0(224)バイト使用してるようです。
なぜ(何に)こんなにも多く使うのでしょうか?

環境は、Vista Home Premium、Microsoft Visual C++ 2010 Express です。

A 回答 (3件)

アセンブリ出力見ればよいだけではないかと.

    • good
    • 0
この回答へのお礼

さっそく見てみました。

int null(void)
{
push ebp
mov ebp,esp
sub esp,0CCh
push ebx
push esi
push edi
lea edi,[ebp-0CCh]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
 int a;
 return null();
call null
}
pop edi
pop esi
pop ebx
add esp,0CCh
cmp ebp,esp
call __RTC_CheckEsp
mov esp,ebp
pop ebp
ret

pushされてるのは、eip, ebp, ebx, esi, ediの5つで20バイト。
それ以外にcc(204)バイトが使われているようですね。
定数で埋め尽くされることと、変数1つで大きさが12バイト変化するので、デバッグ用だろうと推定しました。
が、具体的に何に使われてるかは不明ですね。

回答ありがとうございました。

お礼日時:2012/03/12 01:38

__RTC_CheckEsp という名前でちょろっと検索かけてみると, オーバーランなんかのチェックみたいですね.



参考URL:http://www.glamenv-septzen.net/view/693
    • good
    • 0
この回答へのお礼

その関数はこうなってました。
消費されてる領域とは、直接の関係はないようです。

回答ありがとうございました。

__RTC_CheckEsp:
jmp _RTC_CheckEsp

_RTC_CheckEsp:
jne esperror
ret

お礼日時:2012/03/12 12:09

releaseビルドかdebugビルドかでも変わりますが、ローカル変数だけでなく戻り番地とかレジスタを退避するのでスタックフレームのサイズは大きいです。

あとコンパイルがC++かC言語かとか呼出規約がcdeclやstdcallなのかとかでも変わると思います。

「コールスタック - Wikipedia」
http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC% …
「呼出規約 - Wikipedia」
http://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA% …
    • good
    • 0
この回答へのお礼

そうか~、最近レジスタは多いですからね。

問題が起こってるのはdebugビルドです。

ありがとうございました。

お礼日時:2012/03/11 15:47

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!