67

スタックとヒープが衝突するとどうなるか知りたいです。誰かがこれに遭遇した場合は、シナリオを説明してください。

4

6 に答える 6

76

最新の OS で実行されている最新の言語では、スタック オーバーフロー (万歳!) が発生するかmalloc()sbrk()ヒープmmap()を拡張しようとすると失敗します。しかし、すべてのソフトウェアが最新であるとは限らないため、障害モードを見てみましょう。

  • スタックがヒープに達すると、通常は C コンパイラが静かにヒープのデータ構造を上書きし始めます。最新の OS では、スタックが無限に大きくなるのを防ぐ1 つ以上の仮想メモリガード ページが存在します。ガード ページのメモリ量が、増大するプロシージャのアクティベーション レコードのサイズと少なくとも同じ大きさである限り、OS はセグメンテーション違反を保証します。MMU のないマシンで DOS を実行している場合は、おそらくうんざりしています。

  • ヒープがスタックに達すると、オペレーティング システムは常に状況を認識し、何らかのシステム コールが失敗します。の実装は、malloc()ほぼ確実に失敗に気づき、 を返しますNULL。その後どうなるかはあなた次第です。

OS がガード ページを配置してスタック オーバーフローを防止することを望んでいるコンパイラ作成者の意欲には、いつも驚かされます。もちろん、このトリックは、それぞれが独自のスタックを持つ何千ものスレッドを持つようになるまでうまく機能します...

于 2009-08-26T15:03:30.870 に答える
43

これはプラットフォームに依存します。多くのプラットフォームでは、実際にはまったく発生しません(ヒープとスタックは異なるページに割り当てられており、2つが一致する必要はありません。

ヒープが上向きに成長し、スタックが下向きに成長するという考えは、概念的なものにすぎないことに注意してください。非常に小さなシステム(CP / Mを実行していた古い8ビットマイクロなど)や一部のPICやその他のフラットメモリモデルシステム(MMUやその他の仮想メモリまたは保護されたメモリをサポートしていないシステム)では、ヒープとスタックが実際に存在する可能性がありますこのように実装されました。その場合、動作は未定義になります...しかし、コードが破損したスタックの最上位のアドレスに戻ろうとしたり、ヒープのある部分から別の部分への間接ポインターをたどろうとしたりすると、ほぼ確実にクラッシュします。 ..

いずれにせよ、最新の汎用ワークステーションやサーバーでは表示されません。リソースの制限に達してmallocの障害が発生するか、仮想メモリにぶつかると、最終的にシステムは「赤いスイッチを押す」という震える山にぶつかります。

于 2009-08-26T11:36:27.220 に答える
11

そんな時こそ、エゴン・スペングラー博士の賢明な言葉に頼る時が来ました....

  • エゴン・スペングラー博士: 言い忘れた非常に重要なことがあります。
  • ピーター・ベンクマン博士: なに?
  • Egon Spengler 博士: ヒープをスタックと衝突させないでください。
  • ピーター・ベンクマン博士: なぜですか?
  • エゴン・スペングラー博士: それはまずいでしょう。
  • Dr. Peter Venkman: ここでの「良い/悪い」全体について、私は少しあいまいです。「悪い」とはどういう意味ですか?
  • Egon Spengler 博士: すべての生命が瞬時に停止し、体内のすべての分子が光速で爆発することを想像してみてください。
  • レイ・スタンツ博士: 完全な陽子反転!
  • ピーター・ベンクマン博士: それはまずい。わかった。よし、重要な安全上のヒント。ありがとう、エゴン。
于 2009-08-26T15:09:07.287 に答える
8

運が良ければ、メモリ不足の例外またはスタックの例外が発生します。運が悪ければ、プログラムは無効なメモリに向かい、不良メモリ例外をスローします。非常に不運な場合、プログラムは実行され、実行すべきではないものを破棄し、プログラムが失敗した理由がわかりません。

もちろん、最終的には宇宙が割れる可能性があります。

于 2009-08-26T11:30:37.077 に答える
1

スタック オーバーフロー エラーが発生します。または、malloc() などの新しいヒープ メモリ割り当て関数が失敗します。

于 2018-09-18T19:41:09.203 に答える