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

说说C/C++结构体大小计算(内存对齐)

1. 默认的对齐规则:

1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

2. 对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值

        - Visual Studio 中默认的值为 8

        - Linux中 gcc 没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩

3. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的 整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。

几个例子与结果:

 

2. 修改默认对齐数:

#pragma pack(1) // 设置默认对齐数为1#pragma pack()  // 取消前面设置的默认对齐数

例子: 

在C++中,如果一个结构体(类)中,没有任何成员变量只有成员函数,他的大小是1,因为总要标识这个对象在哪~

3. C++继承场景下的类的大小的计算:

1. 包含虚函数的类

最后说一下在继承的场景下类的大小,我们直接用结果来解释原理~

这里为什么base的大小是12呢?

4 + 1 + 填充3 + vptr(32位下4字节/64位下8字节)

因为类中有一个虚函数,编译器会为对象隐式添加一个vptr虚函数指针,指向这个对象的虚函数表。

2. 包含成员函数的类

 这里说明了一个问题,this指针一定是不存储在对象中,而是在栈空间中~。

4. 扩展:

定义一个计算成员变量在类中偏移量的宏

#define OFFSETOF(TYPE, ELEM) ((int)(&(((TYPE*)0)->ELEM)))

做法:

 

比如,_c 是的地址是0x00000004,它的偏移量正好就是4~

疑问:

((TYPE*)0)->ELEM 不会野指针吗~?答案是不会的,现代的编译器十分智能,它如果检测到((TYPE*)0)->ELEM 之前还有一个&取地址符号,那么他就不会去访问这块空间,而仅仅是拿到他的地址。如果只写((TYPE*)0)->ELEM ,那么必然是会野指针的~~!

 

http://www.xdnf.cn/news/6134.html

相关文章:

  • 【MyBatis-9】MyBatis分页插件PageHelper深度解析与实践指南
  • 朱老师,3518e系列,第二季
  • (3)python开发经验
  • nacos:服务注册原理
  • 我的多条件查询
  • MCP(一)——QuickStart
  • Java—— 可变参数、集合工具类、集合嵌套
  • Vue.js---嵌套的effect与effect栈
  • Maven构建流程详解:如何正确管理微服务间的依赖关系-当依赖的模块更新后,我应该如何重新构建主项目
  • D. Eating【Codeforces Round 1005 (Div. 2)】
  • Spring 中常见的属性注入方式(XML配置文件)
  • 单调栈简单习题分析
  • Web安全核心内容与常见漏洞总结
  • EasyConnect卸载大汇总
  • vulnhub靶场——secarmy
  • 动态多因子策略
  • RDD的自定义分区器
  • stm32 ADC单通道转换
  • 反射, 注解, 动态代理
  • 【PSINS工具箱】基于工具箱的单独GNSS导航、单独INS导航、两者结合组合导航,三种导航的对比程序。附完整的代码
  • 一文理解扩散模型(生成式AI模型)(2)
  • 使用 Docker Desktop 安装 Neo4j 知识图谱
  • VastBase的日常操作记录
  • Qt功能区:简介与安装
  • JS中本地存储(LocalStorage)和会话存储(sessionStorage)的使用和区别
  • vscode - 笔记
  • Deep Learning(手写字识别 - CNN)
  • Python算法思想
  • 企业级IP代理解决方案:负载均衡与API接口集成实践
  • 【导航信号模拟器】【MATLAB APP】MATLAB AppDesigner基本使用教程