结构体的内存对齐与位段的结构体实现

 求结构体总大小(字节数)的规则

  • 结构体第一个成员在结构体变量偏移量从0开始地址数
  • 结构体其余成员对齐数的整数倍的地址数
  • 对齐数:默认的对齐数与结构体成员大小的较小值
  •   vs的对齐数为8 / linux没有对齐数概念
  • 结构体总大小(字节数)为最大对齐数(结构体成员的字节数)的整数倍
  • 结构体嵌套的对齐数为整个结构体最大的对齐数的整数倍的地址,结构体总大小为所有对齐数的整数倍

为什么存在内存对齐

1.(平台/移植)原因:让数据只存在可以被访问的地址上,不会抛出异常,不是 所有 硬件可以             访问任意地址的数据,只能访问某些地址处取某些特定类型数据,否则抛出异常

2.(性能)原因:数据结构(尤其是栈)尽可能在自然边界上对齐,访问未对齐的内存,这需要两               次读取,对齐的内存,则仅需要读取一次(每次访问4个字节)

建议:让占用空间小的成员尽量放在一起,节省空间

修改对齐数:

  1. #pragma pack(2) 有参则设置默认对齐数 无则取消设置的默认对齐数
  2. pack(1) 没有偏移 顺着放
  3. 建议:如果结构体对齐方式不合适的话,可以自己进行手动修改默认对齐数
  4. offsetof (头文件 stddef.h)
  5. 计算结构体的某变量相对于首地址的偏移量
  6. offsetof(结构体类型,结构体内的某变量

结构体传参(传值和传址)

1.结构体传值,形参时实参的一个拷贝,函数调用一次,内存会每调一次开辟与结构体变量     一样大的空间

   (参数在内存中是压栈,时间和空间的开销,系统开销大)

2.结构体传址,不会内存开辟,但是会改变结构体变量的值

结构体实现位段

位段的存在原因:为你所需分配足够的内存空间

位段成员必须是整形家族(常见是int,unsigned int,signed int )

//结构体实现位段 struct A { int _a : 2; // 后面的数字代表占几个bit位 int _b : 3; int _c : 4; };

//结构体实现位段
//书写方式 类型 变量名 : 数值
struct A
{
    int _a : 2; // 后面的数字代表占几个bit位
    int _b : 3;
    int _c : 4;
};

位段的内存分配

位段的空间上是按照需要4个字节int或一个字节char的方式开辟

一个字节先用低地址

在用高地址 剩下的成员不够用会浪费

位段的不确定因素,微端不确定不跨平台,注重可移植性的避免使用位段

位段的跨平台性

1.int位段被当做int还是unsigned来处理

2.位段中的成员在内存中是从左到右,还是从右到左分配

3.位段中最大的数目不确定(不同机器位数不一样,小的位数机器,你写的超过了最大位数,     会出错)

4.当一个结构包含两个位段,第二个位段成员较大,无法容纳第一个位段成员剩余的位数,     剩余的位数是舍弃还是利用,不确定

注意:与结构体相比,位段可以达到同样效果,可以更好节省空间,但是平台可移植性还是存在

网络数据包发送,你需要多大空间,给多大空间,能够节省空间,不会过多浪费

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值