您的位置:首页 > 编程语言 > C语言/C++

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位机器下
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的内存空间是这样的:



内存分配过程:
1、char和编译器默认的内存缺省分割大小比较,char比较小,分配一个字节给它。
2、int和编译器默认的内存缺省分割大小比较,int比较小,占4字节。只能空3个字节,重新分配4个字节。
3、short和编译器默认的内存缺省分割大小比较,short比较小,占2个字节,分配2个字节给它。
4、对齐结束类本身也要对齐,所以最后空余的2个字节也被test占用。
(2)对于类test2的内存空间是这样的:



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)。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: