8

簡単なプログラムを作成しました:

#include <stdio.h>

int main()
{
    int s1;
    int s2;
    int s3;
    
    int *p1, *p2, *p3;
    
    p1 = &s1;
    p2 = &s2;
    p3 = &s3;
    
    printf("%d\n%d\n%d", p1, p2, p3);
}

このプログラムを実行すると、ポインタp1のメモリ アドレスが出力されます。興味深いことに、これらの値には. この背後にある理由を知りたいです。アドレスが だけ異なるのはなぜですか?p2p31212

注: これは、プログラムを実行するたびに発生します。

出力:

ここに画像の説明を入力


多くのタイプの変数で同じプログラムをテストしましたが、得られる結果は..

変数がchar型の場合。 ここに画像の説明を入力


変数が long 型の場合 ここに画像の説明を入力


int array を宣言すると、各配列のサイズは 1 になります。 ここに画像の説明を入力


2 番目に宣言された配列のサイズが 2 の場合、余分な 4 バイトのオフセットが取得されます。 ここに画像の説明を入力

4

2 に答える 2

16

これはデバッグビルドだと思います。Visual Studio 2010 でビルドしたこのプログラムを試してみました。デバッグ時に、アドレス間に 12 バイトの違いがあります。リリース モードでは、4 バイト ( sizeof(int)) の違いがあります。

デバッグ ビルドでは、MSVC コンパイラは余分なデータを追加して、バッファ オーバーフローと初期化されていないメモリの使用を検出できるようにします。printfステートメントにブレークポイントを置き、が指すメモリを表示すると、メモリに表示されるp1はずccです。

メモリが初期化されるさまざまなマジック値がいくつかあります。 cccccccc初期化されていないスタック領域を示します。詳細なリストについては、次の質問に対する回答を参照してください: Visual Studio C++ では、メモリ割り当ての表現は何ですか?

于 2013-05-15T21:42:00.940 に答える
5

これは、「コンパイラーが、書き込みを行ってはならない場所への書き込みを検出するために余分なものを追加する」場合であると確信しています。Microsoft はこれを好んで行っており、コードが悪いことを行っていることを検出できるようになっています。次のようなものを試してください:

void func()
{
  int x = 18;
  int *px = &x;
  px[1] = 4711;
  cout << "px = " << px << " x = " << x << " px[1] = " << px[1] << endl;
}

そして、コンパイラがこのコードが悪いことをしていることを「検出」しないかどうかを確認します...もしそうなら、それはxとpの間に「パディング」が置かれているためであり、関数がそれらの「パディング」領域を返すときにチェックします触れていません。

于 2013-05-15T21:41:36.203 に答える