首页 > 系统相关 >结构体的内存对齐与位段的结构体实现

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

时间:2022-11-03 00:47:57浏览次数:39  
标签:int 位段 地址 内存 对齐 结构

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

  • 结构体第一个成员在结构体变量偏移量从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.当一个结构包含两个位段,第二个位段成员较大,无法容纳第一个位段成员剩余的位数,     剩余的位数是舍弃还是利用,不确定

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

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

标签:int,位段,地址,内存,对齐,结构
From: https://www.cnblogs.com/worker618/p/16853069.html

相关文章

  • 关于Java的volatile关键字、内存屏障的思考
    内存屏障就是一种屏障指令,在X86架构中,指的是加了“lock前缀”的汇编指令在执行时会让CPU或编译器在对内存进行操作的时候,严格按照一定的顺序来执行。也就是说......
  • 电脑内存暴增突然死机idea 文件崩溃导致文件乱码恢复方法
    问题描述 电脑长时间不关机,突然死机,重启电脑后发现该项目的git仓库不能使用了,代码在本地分支,未push到远程分支。并且idea乱码 gitstatus时报错:fatal:notagit......
  • 内存马的攻防博弈实操
    一、概述一文看懂内存马概述:内存马是无文件攻击的一种常用手段,随着攻防演练热度越来越高:攻防双方的博弈,流量分析、EDR等专业安全设备被蓝方广泛使用,传统的文件上传的websh......
  • 关于C语言释放内存的问题
    1、我打算在arg_type使用完成后,进行清理。但是TCFREE(arg_type)这步后,程序报错。(但是在C代码的确是这么写的,不知道是不是因为我的写的是C++的原因) ......
  • (Android图片内存优化)Picasso加载图片 教程。。详细版
    Picasso是Android上一个强大的图片下载和缓存库。示例代码:​​Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);@Override......
  • 垃圾回收与内存泄漏
    一、浏览器的垃圾回收机制1.垃圾回收的概念JavaScript代码运行时,需要分配内存空间来储存变量和值。当变量不在参与运行时,就需要系统收回被占用的内存空间,这就是垃圾回收......
  • 内存高【8】
    windbg分析1.真的是非托管泄漏吗?我在很多分析内存泄漏方面的文章都提到过,先要用二分法确定下是哪一部分的内存泄漏(托管还是非托管)。0:000>!address-summary---U......
  • 字节对齐问题
    概念:CPU每一次读取数据是按照固定起始地址和字节长度读取的比如32位(4字节)的CPU读取起始地址为0x0000,那么其读取数据地址顺序应该是0x0000~0x0003,然后0x0004~0x......
  • 内存高【7】
    windbg分析1.托管还是非托管?既然是内存暴涨,那就看看当前进程的commit内存有多大?0:000>!address-summary---StateSummary----------------RgnCount-------......
  • 嵌入式-C语言基础:malloc动态开辟内存空间
    #include<stdio.h>#include<stdlib.h>intmain(){//char*p;//定义一个野指针:没有让它指向一个变量的地址//*p='c';//直接对野指针进行操作,会报错ch......