我只是在尝试某些东西,我想知道这怎么可能。我有以下代码:
int var1 = 132;
int var2 = 200;
int *secondvariable = &var2;
cout << *(secondvariable+2) << endl << sizeof(int) << endl;
我得到输出
132
4
那么第二个int仅高2个地址怎么可能?我的意思是不应该是4个地址吗?我目前在WIN10 x64下。
致谢
答案 0 :(得分:7)
使用cout << *(secondvariable+2)
时,您不会打印指针,而是在secondvariable[2]
处打印 value ,这是无效的索引,并导致undefined behavior。 / p>
如果要打印指针,则删除取消引用并打印secondvariable+2
。
答案 1 :(得分:3)
由于索引数组超出范围(对于这种情况,单个变量被认为是长度为1的数组),尽管您已经在不确定行为的领域(请参阅Some programmer dude的answer)事项),一些技术背景:
对齐!允许编译器将变量放在地址处,以便可以最有效地访问它们。当您 似乎 通过将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 ++的工作方式。
您不能像这样“导航”您的范围。
这种指针滑稽动作具有完全未定义的行为,因此不应依赖。
您现在不打算在磁带上打孔,而是在编写程序语义的描述,然后由编译器将其转换为机器可执行的东西。
这些抽象的代码,一切都会好起来的。