[c/c++]class/struct数据在内存中的布局
2014-03-09 14:20
204 查看
注明: 以下内容均为学习内容整理,记录,便于自己学习,并非完全意义上的自产,如有感到不适,请联系我
请看下面两段代码 看似一样 但是得到的结果却不同
如果分别对 test1 和test2 执行sizeof 求长度的话那么就会产生两个完全不同的值,前者是20 后者是16。这就牵扯出了struct 和class中的内存布局问题
这个问题的原因是,编译器并不会简单地把结构体内地数据成员紧凑地包裹在一起 而是按照一定地规则去布局。
首先,可以发现地是 test1 中 d 与e 本该是1个字节地,但是在test1地顺序中,却变成了4个字节,这并不是 bool类型真地变成了4个字节,而是编译器为了高效读写数据而对其空位进行地填充(padding)
要理解 为什么要这样填充,我们需要先理解编译器所依照地对齐规则
1.1字节对象,可以置于任何地址
2.2字节对象,可以置于2的倍数地址(地址的LSB为0x0, 0x2,0x4....)
3.4字节对象,可以置于4的倍数地址(地址的LSB为0x0, 0x4,0x8.....)
4.16字节对象,可以置于16的倍数地址 (地址的LSB为0x0)
这么做的原因是因为如果存非对齐的地址读入数据,那么会进行繁杂的 掩码和移位的工作,而对齐的话则不需要
在一个结构体或类中,对齐需求是取其中所有基本类型的成员中的最大对齐需求。
正因为编译器遵循的这个规则,所以编译器会自动的为成员中未达到对齐需求的进行padding操作。如此以来就发生了上面代码中的情况
解决办法也很简单,如上的代码,按顺序对齐就顺利解决了内存浪费的问题
请看下面两段代码 看似一样 但是得到的结果却不同
struct test1 { int a; bool d; int32_t b; bool e; float c; }; struct test2 { int a; int32_t b; float c; bool d; bool e; };
如果分别对 test1 和test2 执行sizeof 求长度的话那么就会产生两个完全不同的值,前者是20 后者是16。这就牵扯出了struct 和class中的内存布局问题
这个问题的原因是,编译器并不会简单地把结构体内地数据成员紧凑地包裹在一起 而是按照一定地规则去布局。
首先,可以发现地是 test1 中 d 与e 本该是1个字节地,但是在test1地顺序中,却变成了4个字节,这并不是 bool类型真地变成了4个字节,而是编译器为了高效读写数据而对其空位进行地填充(padding)
要理解 为什么要这样填充,我们需要先理解编译器所依照地对齐规则
1.1字节对象,可以置于任何地址
2.2字节对象,可以置于2的倍数地址(地址的LSB为0x0, 0x2,0x4....)
3.4字节对象,可以置于4的倍数地址(地址的LSB为0x0, 0x4,0x8.....)
4.16字节对象,可以置于16的倍数地址 (地址的LSB为0x0)
这么做的原因是因为如果存非对齐的地址读入数据,那么会进行繁杂的 掩码和移位的工作,而对齐的话则不需要
在一个结构体或类中,对齐需求是取其中所有基本类型的成员中的最大对齐需求。
正因为编译器遵循的这个规则,所以编译器会自动的为成员中未达到对齐需求的进行padding操作。如此以来就发生了上面代码中的情况
解决办法也很简单,如上的代码,按顺序对齐就顺利解决了内存浪费的问题
相关文章推荐
- c / C++ 中的struct 和memcpy函数 class 对象成员变量内存是否连续
- C++中struct/class的数据对齐与sizeof
- C++对象模型之数据成员内存布局
- C/C++中 union/struct/class的内存对齐
- 查看struct或class的内存布局
- struct型数据的内存布局,struct的对齐方式
- C++ 内存布局(二) 虚继承 ---Empty virtual base classs (空虚基类)
- C++ struct,class的内存对齐
- C++虚继承(四) --- /d1 reportSingleClassLayout插入看类内存布局
- C++ 中struct,class及union 内存空间分配
- c++class 内存布局
- C++ 类中数据在内存的布局
- C++继承中的内存布局
- C++ 对象的内存布局
- C++中struct与class的区别以及联系
- 图说C++对象模型:对象内存布局详解
- c++中struct和class的区别
- C/C++基本数据类型所占字节数及内存字节对齐
- [C++对象模型][6]sizeof与对象内存布局
- [C/C++标准库]_[初级]_[查找内存数据中的指定值]