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 类型时。 在此处输入图像描述


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


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


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

4

2 回答 2

16

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

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

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

于 2013-05-15T21:42:00.940 回答
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 之间放置了“填充”,并检查函数何时返回那些“填充”区域没有被碰过。

于 2013-05-15T21:41:36.203 回答