1. ホーム

test dword ptr [eax],eax ;プローブページです。

2022-02-16 08:56:21

   POJ2593の話題はPOJ2479と全く同じですが、文字列が100000と大きくなることを除けば、POJ2479と同じです。そこで、前回のブログの方法に従って、callMax関数でローカル変数left[100000]とright[100000]を宣言し、main関数でローカル変数a[100000]も宣言して実行したところ、何かおかしなことになったのです。コンパイル時にはエラーは出なかったのですが、実行時には必ず割り込み例外が発生しました。そこでデバッグしてみると、int left[100000];と宣言した後、さらに下にジャンプするとエラーになり、アセンブリ文 ""test dword ptr [eax],eax ; プローブページで止まっていることが判明しました。不思議に思ってググってみたら、スタックオーバーフローと判明。

   これは、ローカル配列の変数定義で割り当てられる最大空間の設定の大きさと関係があります。ローカル変数のアプリケーションスペースはスタックに格納されますが、ウィンドウズのデフォルトのスタックメモリは1Mなので、アプリケーションスペースが1Mより大きくなるとオーバーフローエラーが発生します。

   ウェブ上での解決策は、スタックスペースのサイズを拡大することです

   VSの場合:プロジェクト->プロパティ->リンカー->システム->スタック予約サイズ

   注:ここにはバイト数が記入されています
   2Mに拡張するなら1024*1024*2=2097152、あとはコンパイルして実行すれば合格です。


   もちろん、VSのプロパティを変更するのは億劫です。私がやったことは

   ローカル変数をグローバルスコープに移動させ、スタック容量の制限がないようにする。しかし、グローバル変数の名前を変更しなければなりません。なぜなら、left と right はすでに名前空間 std を使ってその名前の変数を持っており、コンパイラーは "left is not clear" と報告してしまうからです。そこで、left1 と right1 という名前に変更して、コンパイルして合格しました。コンパイルはパスし、実行もパスしました。