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

时间:2013-05-15 21:29:49

标签: c visual-c++ pointers memory

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

#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);
}

每当我运行此程序时,它会打印指针p1p2p3的内存地址,有趣的是这些值的差异为12。我想知道这背后的原因。为什么地址因12而异?

注意:每次我执行程序时都会发生

输出:

enter image description here


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

当变量是char类型时。  enter image description here


当变量是长类型时 enter image description here


当我声明int数组时,每个数组的大小为1。 enter image description here


当第二个声明的数组的大小为2时,它会获得额外的4个字节偏移量。 enter image description here

2 个答案:

答案 0 :(得分:15)

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

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

内存初始化有许多不同的魔术值。 cccccccc表示未初始化的堆栈空间。有关更详细的列表,请参阅此问题的答案:In Visual Studio C++, what are the memory allocation representations?

答案 1 :(得分:5)

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

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

并查看编译器是否“检测”此代码正在执行错误的操作...如果确实如此,那是因为它在x和p之间放置了“填充”,并检查函数何时返回那些“填充“没有触及的区域。