内存字节对齐是编译器为了方便CPU快速访问而采用的一种技术。(即通过优化数据在内存中的存储位置来加快cpu访问内存中数据的速度)
内存对齐的字节大小可以通过#pragma pack语句来定义,vs默认是#pragma pack(8),gcc默认是#pragma pack(4).
内存字节对齐主要用于自定义类和结构体等数据类型。 1.某个成员的对齐字节数定义:如果该成员是c++自带类型如int、char、double等,那么其对齐字节数=该类型在内存中所占的字节数;如果该成员是自定义类型如某个class或者struct,那个它的对齐字节数 = 该类型内最大的成员对齐字节数 2.设置了内存对齐为 i 字节,若类中最大成员对齐字节数为j,那么“整体对齐字节”n = min(i, j) 3.变量的对齐规则: 每个成员对齐规则:类中第一个数据成员放在offset为0的位置;对于其他的数据成员(假设该数据成员对齐字节数为k),他们放置的起始位置offset应该是 min(k, n) 的整数倍(n为该类的整体对齐字节) 发现–整体对齐规则:最后整个类的大小应该是n的整数倍 当设置的对齐字节数大于类中最大成员对齐字节数时,这个设置实际上不产生任何效果(实例2);当设置对齐字节数为1时,类的大小就是简单的把所有成员大小相加
补充:64位机中,整型占4字节,short占2字节,长整型占8字节,float类型占4字节,double类型占8字节了。 我们通过以下几个实例来分析 实例1:(没有指定对齐字节,则n = 最大成员(int i)的大小4) class node { char c; //放在位置0,位置区间[0] int i; //4 = n, 那么放置起始位置应该是4的倍数,即4,位置区间为[4~7] short s; //2 < n,那么放置起始位置应该是2的倍数,即8,位置区间为[8~9] } 此时成员共占用[0~9]10个字节,还要整体对齐,大小应该是4的倍数,即12
实例2:(假设指定对齐字节为8,那么n = min(8,4) = 4) class node { int i; //放在位置0,位置区间[0~3] char c; //1 < n, 那么放置起始位置应该是1的倍数,即4,位置区间为[4] short s; //2 < n,那么放置起始位置应该是2的倍数,即6,位置区间为[6~7] } 成员共占据[0~7]8个字节,刚好是4的倍数,因此大小是8
实例3:(假设指定对齐字节是2,则n = min(2,4) = 2) class node { char c; //放在位置0,位置区间[0] int i; //4 > n, 那么放置起始位置应该是2的倍数,即2,位置区间为[2~5] short s; //2 = n,那么放置起始位置应该是2的倍数,即6,位置区间为[6~7] } 此时成员共占用[0~7]8个字节,刚好是4的倍数,因此大小是8
|