C中的变量声明及其内存地址

sid*_*uff 8 c memory pointers visual-c++

我创建了一个简单的程序:

#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);
}
Run Code Online (Sandbox Code Playgroud)

每当我运行这个程序时,它会打印指针的内存地址p1,p2p3有趣的是这些值有不同之处12.我想知道这背后的原因.为什么地址不同12

注意:每次执行程序时都会发生这种情况.

输出:

在此输入图像描述


我在许多类型的变量中测试了相同的程序,我得到的结果是......

当变量是char类型时. 在此输入图像描述


当变量是长类型时 在此输入图像描述


当我声明int数组时,每个数组的大小为1. 在此输入图像描述


当第二个声明的数组的大小为2时,它会获得额外的4字节偏移量. 在此输入图像描述

Ste*_*eve 15

我猜这是一个调试版本.我尝试过使用Visual Studio 2010构建的程序.在调试时,地址之间有12个字节的差异.在释放模式下,存在4个字节(sizeof(int))的差异.

在调试版本中,MSVC编译器会添加额外的数据,以帮助检测缓冲区溢出和使用未初始化的内存.如果你在printf语句上放置一个断点并查看p1你指向的内存,你应该cc在内存中看到.

内存初始化有许多不同的魔术值. cccccccc表示未初始化的堆栈空间.有关更详细的列表,请参阅此问题的答案:在Visual Studio C++中,内存分配表示是什么?


Mat*_*son 5

我很确定这是"编译器放入额外的东西以检测你何时写入你不应该的地方"的情况.Micrsoft确实喜欢这样做,因此它可以检测你的代码何时做坏事.尝试类似的东西:

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

并查看编译器是否"检测"此代码正在做坏事...如果是,那是因为它在x和p之间放置"填充",并检查函数何时返回那些"填充"区域没有被感动.