すいません、完全に錯綜してますね。
思うんですが、3000個のデータを登録するのに毎回一次オブジェクトを
生成するのは無駄なような気がします。
ローカルを一つ作っておいて、それに設定してはmapに追加では駄目なんでしょうか。
その方が早いような気がしますけれど。
基、一時オブジェクトですね。
そうなると、単純な理由ではありませんね。
ためしに、3000個の生成をforでまわしてみてはどうでしょう。
全て同じ引数でかまいません。これでもオーバーするようだと、
疑わしいのはCHogeのコンストラクタ、またはその引数となって
いるもののコンストラクタのどれかぢゃないでしょうか。
VS2003ですが、32byteの構造体で3万個程度はぜんぜんOKでした。
マクロを展開して、
result.insert(std::make_pair(0, CHoge(aaa, 1, 9, 2, ...); //A
result.insert(std::makke_pair(, CHoge(bbb, 2, 9, 4, ...); //B
コンパイラの癖やオプションの設定で異なるかもしれませんが、
BのCHogeはAのCHogeとは別のメモリー上に作られているようです。
get_hoge()は、最初に、
スタック上にsizeof(CHoge)*3000のメモリーを確保しようとして、
失敗しているのだと想像します。
詳しくはアセンブラー出力を眺めてください。
私なら、const CHoge[] = { CHoge(aaa,..), ...};を作ります。
コンパイル時にconst mapを作ってしまう方法は分かりません。識者殿よろしく。
「ウオッチ」で@ESP を監視するのでもよいかも。
>>PATIO
>思うんですが、3000個のデータを登録するのに毎回一次オブジェクトを
>生成するのは無駄なような気がします。
>ローカルを一つ作っておいて、それに設定してはmapに追加では駄目なんでしょうか。
>その方が早いような気がしますけれど。
これ、ためしにやってみましたが、ダメでした。というか、だいぶコードを削っても、
同じようにスタックオーバーフローでした。
void get_hoge(void)
{
#define ADD_HOGE(idx, a, b, c, d, ... ) \
{ \
CHoge(a, b, c, d, ...))); \
}
ADD_HOGE(0, aaa, 1, 9, 2, ...)
ADD_HOGE(1, bbb, 2, 9, 4, ...)
ADD_HOGE(2, ccc, 3, 9, 2, ...)
// 以下3000行程度、ADD_HOGEマクロを使用
}
上のコードは、単にCHogeのコンストラクタとデストラクタを3000回程度コール
するコードとなります。やはり3000行の部分を大幅にカットしないと、スタック
オーバーフローとなります。
ちなみに、3000行の部分を大幅にカットして実行し、デバッガにてデストラクタが
コールされることを確認しました(スタックは関係ないですけど)。
まちがった。
> 私なら、const CHoge[] = { CHoge(aaa,..), ...};を作ります。
const CHoge array[]でござる。
関数内なら、static constね。
>ロマ
返信ありがとうございます。
(ここからVS2008で試しました)
おっしゃる通りでした。右辺値に対するポインタを取得して表示させてみたら、
確かに異なっていました。debug でも release でもです。正直驚きました。
(要 #pragma warning(disable: 4238) )
ちなみに、
CHoge* ptr;
#define ADD_HOGE \
{ \
ptr = &CHoge(", ", 0, 0, 0, ...); \
printf(%d , ptr); \
}
CHoge の引数の数は60個です(先頭2個はstd::string、残りはint)。
release にて、ADD_HOGE を60回コールしたら、最初の59個は同じ値となりました。
60回以下でも似たようなものです。
しかし、70回コールしたら、完全にバラバラな値となりました。
この辺、コンパイラの癖、最適化もしくはその他の事情がありそうですね。
とにかく、一時変数が「一時的ではない」スタックの過度な消費に繋がる可能性が
あることを肝に銘じておきます。
返信してくれたみなさん、ありがとうございました。
えっと、たぶん試されたのは私が言っている方法とは違うと思います。
私が言いたいのは、
CHogeにメンバーを一気にセットするSetメソッドを作成しておいて
ロカールに
CHoge work(", ", 0, 0, 0, ...);
と作成しておき、
work.Set(aaa, 1, 9, 2, ...);
としてから
result.insert(std::make_pair(0, work));
とすればいいんではという意味です。
こうするとローカルには一つしか生成されないはず。
あとはwork.Setとresult.insertの繰り返しになるので
CHogeのオブジェクトの生成はおこらないと思います。
スコープと寿命のところでも書いていますが、
スコープと寿命が必ずしも一致しないなら
マクロでやっている限り、呼び出した数だけ変数ができると思います。