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

150 篇文章 0 订阅

#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;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值