请考虑以下代码:
struct CExample {
int a;
}
int main(int argc, char* argv[]) {
CExample ce1;
CExample ce2;
cout << "Size:" << sizeof(ce1) << " Address: " << &ce1 << endl;
cout << "Size:" << sizeof(ce2) << " Address: " << &ce2 << endl;
CExample ceArr[2];
cout << "Size:" << sizeof(ceArr[0])<< " Address: "<< &ceArr[0] <<endl;
cout << "Size:" << sizeof(ceArr[1])<< " Address: "<< &ceArr[1] <<endl;
return 0;
}
输出示例:
ce1:尺寸= 4,地址:0039FAA0
ce2:尺寸= 4,地址:0039FA94
ceArr [0]:大小= 4,地址:0039FA84
ceArr [1]:大小= 4,地址:0039FA88
使用代码,前两个对象(ce1和ce2)的地址之间有一个12字节,但是数组中的对象之间只有4个字节的差异。
我认为数据对齐会与问题有关,但我仍然感到难过。知道这里到底发生了什么吗?
答案 0 :(得分:15)
因为数组中的对象必须是连续的。在堆栈上连续声明的对象(在源代码中,而不是机器上)不是[必须是连续的],尽管它们可以是。
答案 1 :(得分:6)
标准对此没有任何说明。编译器可以自由地在项目之间插入它想要的任何填充。
(如果我不得不猜测,我猜你的编译器在调试模式下实现某种形式的堆栈保护/ canary(并且你在调试模式下编译))
答案 2 :(得分:1)
编译器不仅使用堆栈来保存局部变量 - 它还将它用于参数传递,以及由std::cout
引起的一些开销。这可能是变量之间的额外空间用于。
如果您改为制作变量static
,请执行以下操作:
static CExample ce;
static CExample ce2;
static CExample ceArr[2];
...变量将被放置在BSS内存中,并且对齐更可能是您期望的。
其他答案澄清了数组打包和个别项目的原因......
答案 3 :(得分:0)
原因是,在大多数体系结构中,未对齐的负载很慢。有关详细解释,请参阅data structure alignment上的维基百科条目。编译器将每个数据结构放在数据字的开头。但是,在数组中,项目是连续放置在内存中的(如C ++标准所要求的那样)。