【C/C++】如何求出类对象的大小----类结构中的内存对齐


每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”

绪论​:
通过本章你能具体的了解到,如何计算出一个类的大小,并且了解其中到底是如何算的以及了解到为什么需要内存对齐这种算!
————————
早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。

类对象的大小

  • 类对象的大小来说仅由成员影响,成员函数不影响:
  • 因为:在C++中成员函数实际上是在编译时被解析并绑定到特定的对象上,通过对象来调用这些方法并不会增加对象本身的存储需求。
  • 具体来说,在创建一个类的实例时,只有成员变量会被分配内存空间,而成员函数则存在于程序的代码段中。即使增加了更多的内联或非内联成员函数,也不会改变单个类实例所占用的内存大小。
    ——
    但注意的是当要计算一个类的大小的时候,并不是直接通过查看类中成员的类型和个数,最终算出的所占字节决定的决定的!
    ——
  • 而是:成员在不同类型和个数影响大小的基础上引入了内存对齐

那内存对齐到底是什么?让我们接着往下看!

首先理解为什么要内存对齐

  1. 不是所有的硬件平台都能访问任意地址上的任意数据的:某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。(如取:int的4byte)
  2. 性能原因:因为假如在没有内存对齐的情况下:当一个类中刚好有两个成员:char 、int
    1. 此时不进行内存对齐,那么 char的1byte和int的4byte将会连在一起
    2. 假设要取其中的int,那么读取过程中从前往后的找int(每次读取4byte),但因为是char和int连着存放:
    3. 其中会有3byte和char连在一起(读取了前4byte,因为存在一些int,但其中第1byte并不是int的,也代表还没读取完)
    4. 所以还得继续读取还剩的1byte,那么就需要再一次进行读取,才能将int读完
    5. 也就代表需要读取两次才能将一个int读取完
    6. 但假如使用了内存对齐,将int对齐到倍数位置,就能很方便的不需要过滤char的,直接一次性读完
  3. 总体来说:结构体的内存对齐是拿空间来换取时间的做法

话不多说那么我们就快速的来看内存对齐的规则到底是什么,这么算出类对象大小


对齐规则

  • 首先我们理解对于变量,他们都是放到栈区的:
  • 而栈区:其实可以把他想象成一个竖起来的数组!
  1. 第一个参数直接放入,对齐到偏移量为0的位置
  2. 从第二个成员变量开始要对齐到偏移量为自身对齐数的整数倍
    1. 自身对齐数 = 判断自身大小 和 系统默认对齐数 进行比较,取较小值为对齐数(有点抽象先看着后面有例子!)
  3. 结构体的总大小:最终要为所有成员变量中的取过的最大对齐数的整数倍
  4. 如果有镶嵌结构体
    1. 那这个最大对齐数的判断也要包括所镶嵌的结构体 内的 成员的对齐数
    2. 并且这个镶嵌结构体也要对齐到自身的最大的对齐数上(在外部的结构体内)
  5. 附:在Linux gcc 环境下没有默认对齐数 对齐数就是其本身大小、计算偏移量的宏offsetof(类名,成员名)

例子结构如下:

struct/class S1
{char c1;int i;char c2;
};

分析:

  1. 首先将 c1(1byte) 直接放到 0 偏移量处,并占1byte
  2. 从第二个开始就要把成员,放到 自身对齐数的整数倍处!
    1. 也就是 i (int)放到自身对齐数整数倍处:自身对齐数 = 4 (取 自身大小4 和 默认对齐数8 的较小值)
    2. 那么从 就要放到 3 偏移处(从0开始:0 ~ 3 = 4),并占4byte(此时总大小就是 0 ~ 3 + 4 = 8)
    3. 在放一个 c2 ,对齐数为 1(1 > 8),此时总大小就占了9byte了
  3. 最终的大小等于:在成员中自身对齐数最大的数4的整数倍( 1 4 1)
  4. 所以还得让总大小值是4它的倍数:9 - > 12大小
    栈的存储过程图:
    在这里插入图片描述
struct name
{int a;char b;int c;int d;
};

4 + 1 + 3(偏移)+ 4 + 4 = 16
在这里插入图片描述


本章完。预知后事如何,暂听下回分解。

如果有任何问题欢迎讨论哈!

如果觉得这篇文章对你有所帮助的话点点赞吧!

持续更新大量C++细致内容,早关注不迷路。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/25184.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发第4篇__关于在鸿蒙应用中使用Java语言进行设计

本博文很重要 HarmonyOS从 API8 开始不再支持使用Java作为开发语言,未来的新功能将在ArkTS中实现. API 8对应的是HarmonyOS 3.0.0版本。请看下图: 因此, 读者如果看到类似《鸿蒙应用程序开发》(2021年版本 清华大学出版计)书 还使用Java语言…

【图文详解】论文《Attention Is All You Need》中位置嵌入(Positional Encoding)的流程和作用

文章目录 前言一、位置嵌入(Positional Encoding)的流程二、位置嵌入的作用三、为什么采用正弦和余弦函数四、位置嵌入示例五、结论 前言 亲爱的家人们,创作很不容易,若对您有帮助的话,请点赞收藏加关注哦&#xff0c…

SpringBoot 使用 spring.profiles.active 来区分不同环境配置

很多时候,我们项目在开发环境和生产环境的配置是不一样的,例如,数据库配置,在开发的时候,我们一般用测试数据库,而在生产环境,我们要用生产数据库,这时候,我们可以利用 p…

Android 常用命令和工具解析之存储相关

1 基本概念 2 命令解读 2.1 adb shell df df 命令主要用于需要检查文件系统上已使用和可用的磁盘空间的数量。如果没有指定文件名,则显示在当前所有挂载的文件系统上可用的空间。其原理是从proc/mounts 或 /etc/mtab 中检索磁盘信息。 注意:df命令并…

基于springboot+vue的融合多源高校画像数据与协同过滤算法的高考择校推荐系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

4个小时开发DeepSeek+baiduNaotu一键生成思维导图

一、引言 最近发现AI生成思维导图的解决方案普遍存在两个断层:用户需手动复制模型输出的JSON数据到脑图软件,且缺乏实时可视化反馈。基于日常使用的BaiduNaotu框架(其轻量级架构与简洁的UI设计已满足基础需求),我决定…

【洛谷贪心算法题】P1094纪念品分组

该题运用贪心算法,核心思想是在每次分组时,尽可能让价格较小和较大的纪念品组合在一起,以达到最少分组的目的。 【算法思路】 输入处理:首先读取纪念品的数量n和价格上限w,然后依次读取每件纪念品的价格,…

【Azure 架构师学习笔记】- Terraform创建Azure 资源

本文属于【Azure 架构师学习笔记】系列。 前言 在实际的企业环境中,很少甚至可以说禁止手动创建资源,因为很容易出错,并且大规模部署时会非常低效。因此大部分企业都会使用工具或者某些服务来实现这种可控,可复用,具有…

JavaAPI(线程)

线程简介 进程(Process) 进程,是正在运行的程序实例,是操作系统进行资源分配的最小单位。 每个进程都有它自己的地址空间和系统资源(比如CPU时间,内存空间,磁盘IO等)。 多个进程…

冯诺依曼体系结构 ──── linux第8课

目录 冯诺依曼体系结构 关于冯诺依曼,必须强调几点: 冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系 输入单元:包括键盘, 鼠标,网卡,扫…

7.1 线性代数进行图像处理

一、图像的奇异值分解介绍 A A A 的奇异值定理就是 A T A A^TA ATA 和 A A T AA^T AAT 的特征值定理。 这是本章的内容的预览。 A A A 有两个奇异向量的集合( A T A A^TA ATA 和 A A T AA^T AAT 的特征向量),有一个是正奇异值的集合&#…

Java 大视界 -- Java 大数据在智慧环保污染源监测与预警中的应用(104)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

「慢思考」机理分析:从雪球误差到正确推理概率

在大语言模型(LLMs)的发展历程中, Scaling Laws [1] 一直是推动性能提升的核心策略。研究表明,随着模型规模和训练数据的增长,LLMs 的表现会不断优化 [2]。然而,随着训练阶段规模的进一步扩大,性…

面试问题——如何解决移动端1px 边框问题?

面试问题——如何解决移动端1px 边框问题? 最近,不少小伙伴向我反映,他们在面试中频繁被问到关于1px边框的问题。这个看似老生常谈的话题,没想到在面试中的出现率依然这么高,着实让我有些意外。对于那些对这个问题感到…

全星研发项目管理APQP软件系统:汽车电子与半导体行业的研发管理利器

全星研发项目管理APQP软件系统:汽车电子与半导体行业的研发管理利器 1. 集成化管理优势 1.1 数据一致性 无缝数据流转:集成平台确保数据在不同模块间无缝流转,避免因工具切换导致的数据错误和重复工作。案例:某汽车电子企业使用…

Cascadeur 技术浅析(二):物理模拟

Cascadeur 的物理模拟算法是其核心功能之一,旨在通过模拟真实世界的物理规律,使角色动画更加自然和逼真。 1. 刚体动力学(Rigid Body Dynamics) a. 基本原理 刚体动力学用于模拟角色的骨骼和关节运动,假设角色的每个部分都是刚体(即不会发生形变的物体)。通过应用牛顿…

点云处理入门--PointNetPointNet++论文与代码详解

基础知识 点云数据: 点云是一种通过三维扫描设备或计算机图形学技术获取的三维空间数据,通常由一系列点组成,每个点包含其在三维空间中的坐标(如 x,y,z),有时还可能包含颜色、强度等附加信息。 介绍几种常…

Tomcat介绍

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定&…

DeepSeek-R1-Zero:基于基础模型的强化学习

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列四DeepSeek大模型技术系列四》DeepSeek-…

Redis初识

Redis是什么 Redis是一个在内存中存储数据的中间件,它可以用于作为数据库,用于作为数据的缓存,市面上作为数据缓存的不止Redis一家,但为啥我们要学习Redis呢?因为Redis有一些特性和优点,让Reids在市面上脱…