19

C++ では、スタックが破損する可能性があります。私が推測する 1 つの方法は、境界を越えて配列にアクセスしてスタック変数を上書きすることです。破損する可能性がある他の方法はありますか?

4

6 に答える 6

35
  1. スタックを指すことになるランダム/未定義のポインターを持ち、それを介して書き込むことができます。
  2. アセンブリ関数がスタックを誤ってセットアップ/変更/復元する可能性があります
  3. 宇宙波は、スタック内のビットを反転させる可能性があります。
  4. チップのケーシング内の放射性元素がビットを反転させる可能性があります。
  5. カーネル内の何かがうまくいかず、誤ってスタック メモリを変更する可能性があります。

しかし、これらは C++ に固有のものではなく、スタックの概念がありません。

于 2009-04-05T07:17:46.403 に答える
34

One Definition Rule に違反すると、スタックが破損する可能性があります。次の例はばかげているように見えますが、さまざまな構成でコンパイルされたさまざまなライブラリで数回見ました。

header.h

struct MyStruct
{
   int val;
#ifdef LARGEMYSTRUCT
   char padding[16];
#endif
}

file1.cpp

#define LARGEMYSTRUCT
#include "header.h"

//Here it looks like MyStruct is 20 bytes in size    

void func(MyStruct s)
{
   memset(s.padding, 0, 16); //corrupts the stack as below file2.cpp does not have LARGEMYSTRUCT declared and declares Mystruct with 4 bytes
   return; //Will probably crash here as the return pointer has been overwritten
}

file2.cpp

#include "header.h"
//Here it looks like MyStruct is only 4 bytes in size.
extern void func(MyStruct s);

void caller()
{
   MyStruct s;
   func(s); //push four bytes on to the stack
}
于 2009-04-05T09:59:51.927 に答える
15

スタック変数へのポインターを取得するのは良い方法です。

void foo()
{
  my_struct s;
  bar(&s);
}

bar がポインターのコピーを保持している場合、将来的には何が起こる可能性があります。

要約: スタックを指している浮遊ポインターがあると、スタックの破損が発生します。

于 2009-04-05T10:41:53.870 に答える
8

C++ 標準では、スタック/ヒープは定義されていません。さらに、プログラムで未定義の動作を呼び出す方法は多数あります。そのすべてがスタックを破壊する可能性があります (結局のところ、これは UB です)。簡単に言えば、あなたの質問は漠然としていて意味のある答えが得られません。

于 2009-04-05T07:16:18.763 に答える
5

間違った呼び出し規則で関数を呼び出しています。

(これは技術的にはコンパイラ固有のものであり、C++ の問題ではありませんが、すべての C++ コンパイラがそれに対処する必要があります。)

于 2009-04-05T07:51:11.813 に答える
4

デストラクタ内で例外をスローすることは良い候補です。スタックの巻き戻しが台無しになります。

于 2010-02-24T16:20:56.030 に答える