私はnew()を呼び出すときに私のアプリケーションがメモリ不足の場合、私は例外とmalloc()を得るでしょう私は0のポインタを取得します。アプリのメモリが不足しているとどうなりますか?
しかし、いくつかのローカル変数でメソッドを呼び出すとどうなりますか?彼らはあまりにもメモリを占有します。 「通常の」変数のためにメモリを予約する方法はありますか?だから、たとえnew()が例外をスローしたとしても、それを捕まえるだけで、何かを修正して、いつものようにメソッドを呼び出すことができます。
私はnew()を呼び出すときに私のアプリケーションがメモリ不足の場合、私は例外とmalloc()を得るでしょう私は0のポインタを取得します。アプリのメモリが不足しているとどうなりますか?
しかし、いくつかのローカル変数でメソッドを呼び出すとどうなりますか?彼らはあまりにもメモリを占有します。 「通常の」変数のためにメモリを予約する方法はありますか?だから、たとえnew()が例外をスローしたとしても、それを捕まえるだけで、何かを修正して、いつものようにメソッドを呼び出すことができます。
コンパイラは必要なスタックあたりのメモリの量を知っています。しかし、(再帰によって引き起こされる)スタックの数が十分に多いとプログラムがクラッシュします。これを修正する別の方法はないでしょう。
標準には、と呼ばれる興味深い付属品があります。実装数。これは非規範的(情報的)なので、絶対的な真実として扱われるべきではありませんが、あなたに公正なアイデアを提供します。
あなたのデータは次の3つの方法のいずれかで割り当てられている新規はヒープからメモリを割り当てますが、通常はローカル変数はスタック上にあります。オーバーフローする可能性はありますが、使用するプラットフォームによって異なります。詳細をお知らせください。
C++言語では、ローカル変数のメモリを予約するメカニズムはありません。特定のC++実装および/またはオペレーティングシステムは、スタックサイズの合計を増やす手段を提供するかもしれませんが、これは通常は必要ありません。
newへの呼び出しが失敗した場合、おそらく実際にそれから回復することはほとんどできないことに注意してください。多くの人(私を含む)は、もはや新しい失敗をチェックすることを嫌うことはありません。
新たな失敗:1つの問題は、例外ハンドラ/ロギングロジックがヒープ上にルームを割り当てようとしていることです。これはもちろん失敗します!この「入れ子になったエラー」の可能性を低くするには、プログラムの最初に小さな「パラシュート」(たとえば2kb)を割り当てて、新しいエラーが発生したときにこれを削除します。 –
(もちろん、ほとんどの人は、メモリ不足で呼び出すことができるエラーハンドラを直接呼び出さないことを知っているでしょう...しかし、newは間接的に、例えばstd :: vector <>によって呼び出すことができます。この可能性を排除します。) –
:
重度の再帰を行わない限り、通常はスタック領域を使い果たしてはいけません。
しかし、少なくともいくつかのスタックに十分なメモリを確保しますか? – Michael
はい、そうかもしれません。自己尊重のコンパイラは、尾部の再帰やその他の残虐行為をその知識の中で(あなたの助けを借りて)修正しようとします。これをチェックする良い方法は、フィボナッチを書いて、600のような値を呼び出すことです。 – dirkgently
"スタックごとのメモリ"と言うとき、スタックフレームに関することです。コンパイラはそれを知っています。プログラムが必要とするスタックサイズの合計はコードパスに依存するため、通常はコンパイラが予測することは非常に困難です(不可能ではないにしても)。通常、プログラマは、プログラム(またはスレッドの場合)に必要なスタックサイズを指定します。 – Jeff