您的位置:首页 > 其它

结构体的数组成员变量对齐

2016-01-06 11:36 302 查看
#pragma pack 默认值 通常是8
#pragma pack规定的对齐长度,实际使用的规则是:
结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。
而结构整体的对齐,则按照结构体中最大的数据成员 和 #pragma pack指定值
之间,较小的那个进行。
//************************ stone ***
#include <stdio.h>
#pragma pack(8)
int main(int argc, const char * argv[])
{
struct P1 { //结构体模数 = 2 cmp 8 = 2;(取最小值作为模数)
short a[3]; // 2
char b[3]; // 1
} p1;
//2*3 + 3*1 = 9 结构体大小至少是这个数
//对齐就是加0, 加多少这个结构体就增大多少而已.
//0-5 内存空间是a的,因为short a[3],2*3, 下标从0开始,所以
//成员1的大小刚好是 成员2的起始地址值, 起始地址必须是数据类型长度的整数倍.
//按照这个规律...6肯定是1的整数倍了, 所以不用加0
//排完了 长度是9 , 9再与模数判断, 9是否是模数的整数倍? 9不是2的整数倍, 填补一个0 变成10 , 10是2的整数倍,
// 所以长度是10

//内存中得表现
//a0a0 a0bb
//b0
// 64位CPU 一次读取8个字节,内存对齐是为了提高效率而设计的. 这样就 只读取两次就能拿到全部数据了.

struct P2 {//结构体模数 = 8 cmp 8 = 8;(取最小值作为结构体模数)
short a[3];//2
char * b[3];//8 指针类型是 8个字节
} p2;
// len = 2*3 + 8*3 = 30 至少是这个数
// 0~5 a[3] , 下标6 是否是8的整数倍? 不是, 要添加2个0 +2
// 8~32 b[3], 30+2 是否是模数的整数倍? 是, 长度 = 32;

// 内存中得表现
// a0a0 a000
// b000 0000
// b000 0000
// b000 0000

struct P3 { //结构体模数 = 8 cmp 8 = 8
int b; // 4
struct P2 a[2];//结构体的数据类型长度用,结构体成员中得最大的数据类型长度 = 8
struct P1 c[2]; // 2
} p3;
// len = 4+2*10+2*32 = 88 至少是这个数
// 0~3 b, 下标4 是否是 8的整数倍? 否,加4个0, +4
// 8~71 a[2] , 下标72 是否是2的整数倍?是, 什么也不做
// len = 88 +4 = 92, 是否是模数的整数倍? 92不是8的整数倍,加4个0 , 96是8的整数倍, len = 96

// 内存中得表现
// b000 a0a0
// a000 0000
// b000 0000
// b000 0000
// b000 0000
// a0a0 a000
// b000 0000
// b000 0000
// b000 0000
// a0a0 a0bb
// b0a0 a0a0
// bbb0 0000

struct P4 {
struct P2 * a;
int b;
struct P1 c[2];
} p4;

struct P5 {
char a;
double b;
char c;
} p5;

printf("p1 = %lu\n", sizeof(p1));
printf("p2 = %lu\n", sizeof(p2));
printf("p3 = %lu\n", sizeof(p3));
printf("p4 = %lu\n", sizeof(p4));
printf("p5 = %lu\n", sizeof(p5));

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