2009-04-25 10 views
1

私はnew()を呼び出すときに私のアプリケーションがメモリ不足の場合、私は例外とmalloc()を得るでしょう私は0のポインタを取得します。アプリのメモリが不足しているとどうなりますか?

しかし、いくつかのローカル変数でメソッドを呼び出すとどうなりますか?彼らはあまりにもメモリを占有します。 「通常の」変数のためにメモリを予約する方法はありますか?だから、たとえnew()が例外をスローしたとしても、それを捕まえるだけで、何かを修正して、いつものようにメソッドを呼び出すことができます。

答えて

1

コンパイラは必要なスタックあたりのメモリの量を知っています。しかし、(再帰によって引き起こされる)スタックの数が十分に多いとプログラムがクラッシュします。これを修正する別の方法はないでしょう。

標準には、と呼ばれる興味深い付属品があります。実装数。これは非規範的(情報的)なので、絶対的な真実として扱われるべきではありませんが、あなたに公正なアイデアを提供します。

あなたのデータは次の3つの方法のいずれかで割り当てられている
+0

しかし、少なくともいくつかのスタックに十分なメモリを確保しますか? – Michael

+0

はい、そうかもしれません。自己尊重のコンパイラは、尾部の再帰やその他の残虐行為をその知識の中で(あなたの助けを借りて)修正しようとします。これをチェックする良い方法は、フィボナッチを書いて、600のような値を呼び出すことです。 – dirkgently

+2

"スタックごとのメモリ"と言うとき、スタックフレームに関することです。コンパイラはそれを知っています。プログラムが必要とするスタックサイズの合計はコードパスに依存するため、通常はコンパイラが予測することは非常に困難です(不可能ではないにしても)。通常、プログラマは、プログラム(またはスレッドの場合)に必要なスタックサイズを指定します。 – Jeff

1

新規はヒープからメモリを割り当てますが、通常はローカル変数はスタック上にあります。オーバーフローする可能性はありますが、使用するプラットフォームによって異なります。詳細をお知らせください。

+0

メモリが残っていないため、失敗するまでnewまたはmallocを呼び出すことができます。 次に、100個のローカル整数変数を言ういくつかのメソッドを呼び出します 何が起こりますか?私はいつものように働く方法が必要です。 – Michael

+1

ヒープとスタックは2つの別々のメモリ領域です - 通常は関係ありません。 2Mbのヒープと1Mbのスタックを持つことができます。 – Jeff

+0

@Jeff:現代のプロテクトモードのOSで同じではないが、DOS時代には、スタックとヒープが衝突する可能性があります。基本的に、スタックはメモリの上から成長し、ヒープは成長しました。 –

3

C++言語では、ローカル変数のメモリを予約するメカニズムはありません。特定のC++実装および/またはオペレーティングシステムは、スタックサイズの合計を増やす手段を提供するかもしれませんが、これは通常は必要ありません。

newへの呼び出しが失敗した場合、おそらく実際にそれから回復することはほとんどできないことに注意してください。多くの人(私を含む)は、もはや新しい失敗をチェックすることを嫌うことはありません。

+0

新たな失敗:1つの問題は、例外ハンドラ/ロギングロジックがヒープ上にルームを割り当てようとしていることです。これはもちろん失敗します!この「入れ子になったエラー」の可能性を低くするには、プログラムの最初に小さな「パラシュート」(たとえば2kb)を割り当てて、新しいエラーが発生したときにこれを削除します。 –

+0

(もちろん、ほとんどの人は、メモリ不足で呼び出すことができるエラーハンドラを直接呼び出さないことを知っているでしょう...しかし、newは間接的に、例えばstd :: vector <>によって呼び出すことができます。この可能性を排除します。) –

5

  • 静的に割り当てられたデータ(静的メンバまたはグローバル)アプリの起動時に、彼らは本当に問題ではするつもりはないことを意味し、割り当てられています。
  • スタックに割り当てられたデータがスタックに割り当てられます(驚きです!)スタックは、ローカル変数と関数スタックフレーム用に確保されたメモリ領域です。スペースが足りなくなった場合、何が起こるのかは不明です。いくつかの実装はそれを検出し、アクセス違反/セグメンテーション違反を与える可能性があり、他の実装はヒープデータを上書きするだけです。いずれにしても、これを検出する方法はありません。一般的に、これを処理する方法はないからです。スタック領域が足りなくなった場合は、何もできません。スタック空間を占有するので、関数を呼び出すことさえできません。
  • ヒープ割り当てメモリは、新しい/ mallocを呼び出すときに使用するメモリです。ここでは、メモリが不足している状況を検出するためのメカニズムがあります。 (200MBを割り当てるのではなく、100MBで処理することができ、データを途中まで入れ替えることができます)

重度の再帰を行わない限り、通常はスタック領域を使い果たしてはいけません。

関連する問題