C++笔记——有关内存对齐
2017-12-18 22:39
267 查看
32位编译器: char :1个字节 char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器) short int : 2个字节 int: 4个字节 unsigned int : 4个字节 float: 4个字节 double: 8个字节 long: 4个字节 long long: 8个字节 unsigned long: 4个字节 64位编译器: char :1个字节 char*(即指针变量): 8个字节 short int : 2个字节 int: 4个字节 unsigned int : 4个字节 float: 4个字节 double: 8个字节 long: 8个字节 long long: 8个字节 unsigned long: 8个字节
类的大小:
类的大小只与成员变量(非static数据成员变量)和虚函数指针有关,还要考虑到对齐。
对齐规则理解1:
1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成员大小的整数倍位置。如在32bit的机器上,int的大小为4,因此int存储的位置都是4的整数倍的位置开始存储。
2.结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储。如 struct A 中包含 struct B, struct B 中包含数据成员 char, int, double,则 struct B 应该以sizeof(double)=8的整数倍为起始地址。
3.收尾工作的对齐规则:整个struct的大小,应该为最大数据成员大小的整数倍。
假设在64位机器下
对齐规则理解2:
#include<iostream>
using namespace std;
class test {
private :
char c='1';//1byte
int i;//4byte
short s=2;//2byte
};
int main(){
cout << sizeof(test) << endl;
return 0;
}
输出:12
输出:8
我们可以看到。类test和test2的成员变量完全一样,只是定义顺序不一样,却造成了2个类占用内存大小不一样。而这就是编译器内存对齐的缘故。
(1)对于类test的内存空间是这样的:
![](http://images.cnitblog.com/blog2015/580631/201503/271354292862668.png)
内存分配过程:
1、char和编译器默认的内存缺省分割大小比较,char比较小,分配一个字节给它。
2、int和编译器默认的内存缺省分割大小比较,int比较小,占4字节。只能空3个字节,重新分配4个字节。
3、short和编译器默认的内存缺省分割大小比较,short比较小,占2个字节,分配2个字节给它。
4、对齐结束类本身也要对齐,所以最后空余的2个字节也被test占用。
(2)对于类test2的内存空间是这样的:
![](http://images.cnitblog.com/blog2015/580631/201503/271358145999734.png)
1、int和编译器默认的内存缺省分割大小比较,int比较小,占4字节。分配4个字节给int。
2、char和编译器默认的内存缺省分割大小比较,char比较小,分配一个字节给它。
3、short和编译器默认的内存缺省分割大小比较,short比较小,此时前面的char分配完毕还余下3个字节,足够short的2个字节存储,所以short紧挨着。分配2个字节给short。
类的大小:
类的大小只与成员变量(非static数据成员变量)和虚函数指针有关,还要考虑到对齐。
对齐规则理解1:
1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成员大小的整数倍位置。如在32bit的机器上,int的大小为4,因此int存储的位置都是4的整数倍的位置开始存储。
2.结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储。如 struct A 中包含 struct B, struct B 中包含数据成员 char, int, double,则 struct B 应该以sizeof(double)=8的整数倍为起始地址。
3.收尾工作的对齐规则:整个struct的大小,应该为最大数据成员大小的整数倍。
假设在64位机器下
class test1 { int a; //内存位置:[0]..[3] char b; //内存位置:[4] int* c; //内存位置:[8]..[15] } sizeof(test1) = 16 class test2 { short x; //内存位置:[0]..[1] double y; //内存位置:[8]..[15] test1 t; //内存为止:[16]..[32] char z; //内存为止:[17] } sizeof(test2) = 2 + (6) + 8 + 16 + 1 + (7) = 40
对齐规则理解2:
#include<iostream>
using namespace std;
class test {
private :
char c='1';//1byte
int i;//4byte
short s=2;//2byte
};
int main(){
cout << sizeof(test) << endl;
return 0;
}
输出:12
class test2 { private: int i;//4byte char c = '1';//1byte short s = 2;//2byte }; int main(){ cout << sizeof(test2) << endl; return 0; }
输出:8
我们可以看到。类test和test2的成员变量完全一样,只是定义顺序不一样,却造成了2个类占用内存大小不一样。而这就是编译器内存对齐的缘故。
(1)对于类test的内存空间是这样的:
![](http://images.cnitblog.com/blog2015/580631/201503/271354292862668.png)
内存分配过程:
1、char和编译器默认的内存缺省分割大小比较,char比较小,分配一个字节给它。
2、int和编译器默认的内存缺省分割大小比较,int比较小,占4字节。只能空3个字节,重新分配4个字节。
3、short和编译器默认的内存缺省分割大小比较,short比较小,占2个字节,分配2个字节给它。
4、对齐结束类本身也要对齐,所以最后空余的2个字节也被test占用。
(2)对于类test2的内存空间是这样的:
![](http://images.cnitblog.com/blog2015/580631/201503/271358145999734.png)
1、int和编译器默认的内存缺省分割大小比较,int比较小,占4字节。分配4个字节给int。
2、char和编译器默认的内存缺省分割大小比较,char比较小,分配一个字节给它。
3、short和编译器默认的内存缺省分割大小比较,short比较小,此时前面的char分配完毕还余下3个字节,足够short的2个字节存储,所以short紧挨着。分配2个字节给short。
c语言中变量存储为什么要内存对齐?
为了有助于加快计算机的取数速度,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基数据类型(int等)都位于能被4整除的地址上,以此类推。这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。
字节对齐的细节和编译器实现相关,但一般而言,满足三个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
相关文章推荐
- C++学习笔记(二) bool const 和 #define 结构体内存对齐
- 笔记7:结构体内存对齐
- C/C++学习笔记8:内存中数据对齐的问题总结
- 与内存对齐有关的sizeof
- 学习笔记-C/C++-结构体与sizeof,内存对齐的题目怎么做
- (摘抄笔记)从一道面试题看struct中的内存对齐
- 学习笔记-C/C++-结构体与sizeof,内存对齐的题目怎么做
- 深入理解计算机系统学习笔记(三)之C语言常见的与存储器(内存)有关的错误
- 有关内存对齐的问题
- C++学习笔记2--函数重载 复杂的数据 内存对齐 指针数组 结构与指针 传值传址传引用 联合枚举类型别名
- 一篇有关内存对齐的文章
- 关于内存对齐的学习笔记
- 有关-内存对齐-的总结
- 【并行计算-CUDA开发】有关CUDA当中global memory如何实现合并访问跟内存对齐相关的问题
- 操作系统的内存对齐机制学习笔记
- 【学习笔记】内存对齐
- (转)【D3D11游戏编程】学习笔记十三:内存对齐的一点思考
- 与结构体对齐有关的 分析内存分配的笔试题
- 内存对齐-笔记
- 《c专家编程》笔记--linux内存对齐