当前位置: 首页 > news >正文

计算结构体大小

计算结构体大小

目录

  • 计算结构体大小
    • 一. 结构体内存对齐
      • 1. 简介
      • 2. 嵌套结构体
    • 二. offsetof
    • 三. 内存对齐的意义
    • 四. 修改默认对齐数

一. 结构体内存对齐

以字节(bety)为单位

1. 简介

对于结构体成员在内存里的存储,存在结构体的对齐规则,并不是连续存放的。

例1:对下面程序,你认为结构体s的大小是多少呢?

#include <stdio.h>struct S1
{char a;int b;char c;
};int main()
{struct S1 s;printf("%d\n", sizeof(s));return 0;
}
  • 第一个成员存放的位置是该结构体偏移量为0的地址
    在这里插入图片描述

  • 其他成员变量需要根据偏移量存放在其对齐数的整数倍的位置处

vs 下:对齐数 = 编译器默认对齐数(值为8) 与 该成员变量大小的最小值

(Linux下: 对齐数 = 该成员变量的大小)

在这里插入图片描述


  • 结构体总大小是其每个成员对齐数中最大数值的整数倍
    在这里插入图片描述

2. 嵌套结构体

例2: 对下面代码中,结构体s的大小是?

#include <stdio.h>struct S1
{char a;int b;char c;
};struct S2
{struct S1 s1;char c;
};int main()
{struct S2 s;printf("%d\n", sizeof(s));return 0;
}
  • 包含上述三条规则下,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体总大小为最大对齐数(包含嵌套结构体成员的对齐数)的整数倍
    在这里插入图片描述

二. offsetof

在这里插入图片描述

  • 该宏可以用于计算结果体成员相对于起始位置的偏移量

示例:
在这里插入图片描述

  • 原码解析

    #define offsetof(s,m) ((size_t)&(((s*)0)->m))
    

将数字0(地址为0x00000000)强转为s*类型的数据,s是结构体,m是其成员,

通过&((s* )0->m)得到成员m处的地址,再转换为size_t类型数据(相当于得到m地址距离结构体起始地址0x00000000的偏移字节数)。


三. 内存对齐的意义

  1. 在不同平台下,不是所有硬件平台都可以取任意地址访问数据,某些平台只能在某些地址处取特点大小的数据。
  2. 此时对于内存对齐后的数据,处理器访问会更加便捷

示例:
在这里插入图片描述

结构体内存对齐为了用空间来换取时间

但是我们可以利用结构体内存对齐规则,更合理的设计成员变量位置,如:让占用空间小的成员放在一起。

四. 修改默认对齐数

在vs(Visual Studio)编译器下存在默认对齐数(8)

如果我们想要修改为其他数值,也是可以的。

使用预处理指令#pragma pack(数字),修改成你想要的结果

示例:
在这里插入图片描述

将默认对齐数调至2后,对于结构体s1:a在偏移量0的空间,b在偏移量2~5的空间,c在偏移量6的空间。从0 ~ 6一共7个字节的空间,不是最大对齐数2的整数倍,所有会再浪费1个字节空间,总大小为8个字节。

通常修改的默认对齐数都是2n2^n2n , n=(0,1,2...)n=(0,1,2...)n=(0,1,2...)

s1:a在偏移量0的空间,b在偏移量2~5的空间,c在偏移量6的空间。从0 ~ 6一共7个字节的空间,不是最大对齐数2的整数倍,所有会再浪费1个字节空间,总大小为8个字节。

通常修改的默认对齐数都是2n2^n2n , n=(0,1,2...)n=(0,1,2...)n=(0,1,2...)

🦀🦀观看~

http://www.lryc.cn/news/22192.html

相关文章:

  • 第二十一篇 数据增强
  • 记一次线上es慢查询导致的服务不可用
  • 分布式之ZAB协议
  • MySQL binlog常用命令及设置清理时间
  • Windows下载安装Prometheus
  • 0-1背包、完全背包及其变形【零神基础精讲】
  • OpenStack
  • Spring Boot整合Kaptcha实现验证码功能
  • 【2023】某python语言程序设计跟学第一周内容
  • C#学习记录——接口的实现
  • “ChatGPT之父”Sam Altman:我是如何成功的?
  • jQuery发送Ajax请求的几种方式
  • Android实现连线题效果
  • 以数据 见未来!首届未来数商大会成功举办
  • Java数据结构与算法——手撕LRULFU算法
  • 20230227英语学习
  • 校招前端高频react面试题合集
  • k8s node之间是如何通信的?
  • System V|共享内存基本通信框架搭建|【超详细的代码解释和注释】
  • 魔兽世界WoW注册网站搭建——-Liunx
  • OSG三维渲染引擎编程学习之六十八:“第六章:OSG场景工作机制” 之 “6.8 OSG内存管理”
  • 字节前端必会面试题(持续更新中)
  • 内存数据库-4-[redis]在ubuntu中离线安装
  • 并非从0开始的c++ day8
  • ubuntu下用i686-w64-mingw32交叉编译支持SDL、Openssl的ffmpeg库
  • 对IDEA中断点Suspend 属性理解
  • IM即时通讯开发如何解决大量离线消息导致客户端卡顿的
  • 【软件测试】测试老鸟的迷途,进军高级自动化测试测试......
  • HMM(隐马尔科夫模型)-理论补充2
  • 【分布式系统】MinIO之Multi-Node Multi-Drive架构分析