0

私は最近SECアルゴリズムを書いています(ここのようにhttp://18.7.29.232/bitstream/handle/1721.1/4015/HPCES024.pdf?sequence=2)。最初の再帰バージョンでは、200000 ポイントを超えると「スタック オーバーフロー」例外がスローされるように見えました。自分のスタックに (再帰の代わりに反復を使用して) 書き込むまで理由がわかりませんでしたが、1000000 ポイントで問題なく動作しました。

関数を呼び出すと、プロセッサと変数の命令が「ランダムに」割り当てられたメモリにコピーされると思います。また、クラス ベクトルのグローバル変数を取得した場合は、コンパクトなメモリ (テーブルなど) が必要だと思います。

問題は、(私の意見では)メモリが小さな部分に分割されている場合、ベクトルを「拡大」できず、「スタックオーバーフロー」例外をスローするため、(たとえば、再帰アルゴリズムで)大量の関数呼び出しがある場合です。

したがって、関数インスタンスのメモリをどこに格納する必要があるかをどうにかして c++ に納得させることができると考えました。ここhttp://www.parashift.com/c++-faq-lite/placement-new.htmlのように、「関数インスタンス」のテーブルを作成するため、メモリを台無しにすることはできません。

出来ますか?

4

1 に答える 1

0

vectorスタック オーバーフロー エラーが発生するのは、決して人ではありません。vectorヒープにメモリを割り当てます。これは、合計メモリ (仮想メモリを含む) と同じ大きさになる可能性があります。

一方、スタックは、プログラムが関数のローカル変数やその他のものを保存する(かなり)小さなメモリです。

関数を呼び出すと、次のデータがスタックに書き込まれます。

  • おそらくいくつかのレジスター
  • スタック ポインタ
  • おそらく戻り値のためのスペース
  • 関数の引数 (存在する場合)
  • ベースポインタ
  • 新しい関数のローカル変数

アーキテクチャ/コンパイラによっては、他のデータも存在する場合があります。

そのため、最も単純な関数でさえ、呼び出されるためにスタック上の最小量のメモリを必要とします。幸いなことに、関数が戻ると、それらのメモリは再び利用可能になります。ただし、この関数は返されていませんが、これらのデータは残ります。したがって、関数を再帰的に何度も呼び出すと、これらすべてのデータが互いに積み重なっていきます。再帰関数をすぐに終了しないと、メモリが不足し、スタック オーバーフロー エラーが発生します。

興味がある場合は、追加の変数を関数に追加して (それらが最適化されないように)、より少ない数のポイントでこのエラーが発生することを確認できます。

std::stackあなたの解決策は、コメントで他の人が言っているので、基本的にたとえばを使用してコールスタックをシミュレートする反復アプローチを使用することです。

于 2012-09-01T10:47:42.713 に答える