C ++ /地址空间:每个地址2字节?

时间:2018-09-11 12:02:51

标签: c++ pointers memory-address

我只是在尝试某些东西,我想知道这怎么可能。我有以下代码:

int var1 = 132;

int var2 = 200;

int *secondvariable = &var2;

cout << *(secondvariable+2) << endl << sizeof(int) << endl;

我得到输出

132

4

那么第二个int仅高2个地址怎么可能?我的意思是不应该是4个地址吗?我目前在WIN10 x64下。

致谢

3 个答案:

答案 0 :(得分:7)

使用cout << *(secondvariable+2)时,您不会打印指针,而是在secondvariable[2]处打印 value ,这是无效的索引,并导致undefined behavior。 / p>

如果要打印指针,则删除取消引用并打印secondvariable+2

答案 1 :(得分:3)

由于索引数组超出范围(对于这种情况,单个变量被认为是长度为1的数组),尽管您已经在不确定行为的领域(请参阅Some programmer dudeanswer)事项),一些技术背景:

对齐!允许编译器将变量放在地址处,以便可以最有效地访问它们。当您 似乎 通过将2*sizeof(int)添加到第二个变量的地址来获得有效的输出时,您显然是偶然地到达了第一个 。显然,编译器决定在两个变量之间留一个空隙,以便可以将它们都对齐为可被8整除的地址。

但是请注意,您不能保证这种对齐方式,不同的编译器可能会做出不同的决定(或在另一个系统上使用相同的编译器),甚至可以通过编译器标志来更改对齐方式。

另一方面,保证数组会占据连续的内存,因此在以下示例中您将获得预期的结果:

int array[2];

int* a0 = &array[0];
int* a1 = &array[1];

uintptr_t diff = static_cast<uintptr_t>(a1) - static_cast<uintptr_t>(a0);
std::cout << diff;

强制转换为uintptr_t(或替换为char*)可确保您获得的地址差(以字节为单位)而不是int的大小...

答案 2 :(得分:0)

这不是C ++的工作方式。

您不能像这样“导航”您的范围。

这种指针滑稽动作具有完全未定义的行为,因此不应依赖。

您现在不打算在磁带上打孔,而是在编写程序语义的描述,然后由编译器将其转换为机器可执行的东西。

这些抽象的代码,一切都会好起来的。