2012-03-22 153 views
2

私はVisual Studio 2010を使用しています。スタック上の宣言の最大許容サイズはいくらですか?

私は間違ったエラーを与えていると思います。 配列が、問題は、私は6にTNK_CACHE_SIZEを定義するとき、それは私が時間のコンパイルエラー与えるが、アクセス違反のエラーを持っていない、

ある

struct fpinfo search_buf[TNK_CACHE_SIZE][BUCKETS][B_ENTRIES]; 

として

#define BUCKETS 2048 
#define B_ENTRIES 4096 

typedef struct fpinfo 
{ 
    unsigned long long offset; 
    unsigned long length; 
    char fing_print[33]; 
}fpinfo; 

から定義されます実行時に私はそれに書き込もうとします。

一方、TNK_CACHE_SIZEを3に定義すると、次のコンパイル時エラーが発生します。

1> LINK:致命的なエラーLNK1248:画像サイズ(86CB7000)が最大 許容サイズを超えた(80000000)

1)それがためないながら、なぜそれがコンパイル時に最初の宣言を無視しませんそれは最初のもののちょうど半分だったとき、2番目のものでした。

2)スタック上の宣言の最大許容サイズはいくらですか?

3)は、この許容サイズをプロジェクト内の他のすべてのメモリ割り当てを含めるかこれ以上割り当て可能なメモリ空間と割り当てられることができていない最後のものがあるまで、それは他の後に1つのメモリ割り当てされてい旗がついた?

答えて

2

コンパイラとリンカによる画像サイズのチェックが不完全である可能性があります。それを大きくしすぎると、おそらく計算が折り返して不正確な結果になり、有効な画像サイズの範囲内にあるように見えます。私。あなたのツールチェーンは、大きすぎるイメージサイズで小さなエラーをキャッチしますが、大きなエラーではありません。

86CB,7000の数を2倍にすると、表現するのに32ビット以上必要なもの、つまり1,0D96,E000が得られることに注意してください。計算が32ビットで行われた場合、これはD96,E000に切り詰められ、画像サイズが範囲内に見えるようになりますが、完全に間違っています。

mallocでスペースを動的に割り当てるようにしてください。

2

それはスタック上にこのような大きなオブジェクトを割り当てることは良い考えではありませんが、あなたは二つの方法でMSVCのデフォルトのスタックサイズを上書きすることができます。

  • 使用がで行くプロジェクトのプロパティで/Fオプション( C/C++セクションその後、コマンドラインと書き込み/ F:それは一歩をコンパイルするためにのみ動作するため追加オプションでバイトフィールドとにかくこれは良いアイデアではありませんdリンク。プロジェクトのプロパティ

  • は、システムリンカセクションに移動し、スタック予約サイズフィールドに必要なサイズを記述します。

+1

ここにはマイクロソフトのリンクがあります。http://msdn.microsoft.com/en-us/library/tdkhxaks%28v=vs.71%29.aspx – Alex

+0

リンクに感謝@Alexを忘れました! –

0

3 * 2048 * 4096 * sizeof(pinfo)はギガバイトをはるかに上回ります。それはちょうどあなたのテーブルのためです、そうです、あなたのイメージは巨大になるだろうし、明らかにVSがデフォルトで許すものよりも大きいです。

あなたはそのメモリを動的に割り当てる方がよいでしょう。

/** 
* Allocate memory in a single contiguous block. Be sure to free it 
* when you don't need it anymore. 
*/ 
fpinfo *search_buf_store = malloc(sizeof *search_buf_store * 
            TNK_CACHE_SIZE * 
            BUCKETS * 
            B_ENTRIES); 

/** 
* Declare search_buf as a pointer to a 2-d array, and set it to point 
* to the block we just allocated. You can then index search_buf 
* as you would a regular 3-D array. Just be sure that if you pass search_buf 
* to any functions, you declare it in the parameter list just like it's 
* declared here. 
*/ 
fpinfo (*search_buf)[BUCKETS][B_ENTRIES] = 
    (fpinfo (*)[BUCKETS][B_ENTRIES]) search_buf_store; 
1

単純な事実は、この配列をスタック上で宣言するべきではないということです。

Windowsのスタックサイズはスレッドあたり2Mbです。スレッドあたりであることに注意してください。をスタックにすることができたとしても、システムは停止するようになります。私は仮想メモリのディスクスワッピングがスタックデータのためにサポートされていることさえ確信していませんが、そうした場合、あなたのコードは非常に遅く実行されます。

静的または動的割り当てがより適切ですが、それでもほとんどのシステム、特に32ビットシステムでは負荷が大きくなります。メモリマップファイルを使用するほうが効率的かもしれません。これはディスクスワッピングと同じ方法で動作しますが、OSメモリマネージャーがその決定を非決定論的にするのではなく、明示的に要求しています。

関連する問題