首先,我在谈论32位架构。我的教授给我们举了一个例子,说明如何存储C / C ++ 32位整数的地址,地址为0A0B0C0D
,整数的第一个字节存储在0x0A
,第二个在0x0B
,第三个在0x0C
,第四个在0x0D
。但是,我在C ++中尝试了以下代码:
#include <iostream>
int main(){
int a = 5;
std::cout << &a;
}
我得到了0x7fffba2e6c3c
。但是,这并不像教授给我们的例子那样连续的字节。我的问题是,为什么编译器不将整数的4个字节存储在连续的内存地址中,而不是将整数中的每个字节存储在不同的地址中?
答案 0 :(得分:6)
并且地址为0A0B0C0D,整数的第一个字节存储在0x0A
这里似乎有些混乱。
如果整数的第一个字节存储在0x0A,则整个整数的地址为0x0A。 0A0B0C0D似乎是属于该整数的字节地址的某种串联。
或者相反,如果整数的地址是0x0A0B0C0D,那么第一个字节的地址也是0x0A0B0C0D,第二个字节的地址是0x0A0B0C0E,依此类推。
我得到了0x7fffba2e6c3c。但是,这看起来不像字节是连续的
您已打印整数的地址。您无法从地址判断该地址处的对象是否是连续的。例如,如果您在教授示例中得到了0x0A,那么您如何确定连续字节是否为0x0B?
你不能从地址中得出这样的结论,但你只需要假设连续性。
必须将整数存储在连续的内存地址中吗?
是。所有对象在内存中都是连续的。 (请注意,对象可以包含单独对象的地址,这些对象不一定与保存指针的对象相关地存储。因此,例如,链接列表对象不会连续地存储列表的元素,而是每个节点的列表本身是连续的。)
答案 1 :(得分:3)
必须将整数存储在连续的内存地址中吗?
是的,因为C ++标准§1.8/ 5说:
易于复制或标准布局类型的对象(......) 占用连续的存储字节。
至于你的例子,
然而,这看起来像字节是连续的,就像教授给我们的例子一样。
您误解了输出。您看到的只是int
开始的单个地址。
答案 2 :(得分:2)
所有内置类型(包括整数)都占用内存中的连续字节。
当您将&a
打印到cout
时,您将获得整数的初始字节的地址。其他三个字节存储在它后面。在您的情况下,接下来的三个字节将位于0x7fffba2e6c3d
,0x7fffba2e6c3e
和0x7fffba2e6c3f
。
答案 3 :(得分:0)
然而,这并不是强制性的,如果您以任何其他方式执行此操作,计算机系统/应用程序的内存i / o性能将无法实现最佳和高效。
将应用程序数据存储在内存中的连续区域中可以实现内存级访问优化。为什么?因为当内存访问操作指向连续的内存地址时,内存本身被设计为最佳。
答案 4 :(得分:0)
你的教授错误地把事情写得太近了:)
0A
,0B
,0C
和0D
是整数的四个字节的地址。连续内存意味着整个整数的地址将为0A
。就是这样。
NOT 连接其中的四个,这根本没有意义。
相反,要获取连续内存中第二个字节的地址,只需将1加到第一个字节的地址:0A+1=0B
。
您的代码打印出来的是变量a
的地址;在现实生活中,地址往往是丑陋的,因为虚拟内存,分页,大量的东西加载,什么不是。你可以reinterpret_cast
到char*
并遍历整数的字节:
char* b = reinterpret_cast<char*>(&a); // now *b is the first byte
for(int i=0;i<sizeof(int);i++)
std::cout<< static_cast<int>(*b++) <<' ';
它应该输出三个零和一个5(以平台相关的顺序)