C++内存对齐

目录

    • 定义
    • example
    • class和struct在内存对齐方面的相似性

定义

  1. 内存对齐是指编译器在为结构体或类的成员分配内存时,按照一定的规则将成员存放在特定的内存地址上,使得每个成员的起始地址是某个特定值(通常是成员自身大小或一个指定对齐值的倍数),结束时也要内存也要对齐
  2. 每个特定平台上的编译器都有自己的默认“对齐系数”(32位机一般为4,64位机一般为8)
    1. 我们可以通过预编译命令#pragma pack(k),k=1,2,4,8,16来改变这个系数,其中k就是需要指定的“对齐系数”
    2. 也可以使用#pragma pack()取消自定义字节对齐方式。
    3. 对齐按照对齐系数和自身占用字节数中,二者比较小的那个进行对齐

example

#pragma pack(4)
struct One{double d;char c;int i;
}
// 占用内存字节数 16// #pragma pack(8)
struct Two{char c;double d;int i;
}
// 占用内存字节数 24
// 内存布局:| c (1) | padding (7) | d (8) | i (4) | padding (4) |// #pragma pack(2)
struct Three{char c;double d;char i;
};
// 占用内存字节数 12

class和struct在内存对齐方面的相似性

  • 在C++中,classstruct本质上是非常相似的概念,它们都有内存对齐的特性。这是因为编译器在处理它们的内存布局时,遵循相同的内存对齐规则。
  • 例如,对于基本数据类型成员(如intchardouble等)在classstruct中的存储,编译器都会考虑内存对齐的要求。假设在一个struct中有一个int成员和一个double成员,编译器会根据int(通常4字节)和double(通常8字节)的大小以及当前的对齐设置,在成员之间插入必要的填充字节,以保证每个成员按照合适的边界存储。同样的情况也会发生在class中。
  • 以下是一个简单的示例:
    #pragma pack(8)
    struct MyStruct {char a;int b;
    };
    class MyClass {char c;int d;
    };
    
    在这个示例中,MyStructMyClass在内存布局上会受到相同的内存对齐规则的约束。MyStruct中的charint成员之间会有填充字节(因为int需要4字节对齐),MyClass中的charint成员之间也会有相同的填充字节。
  1. 访问权限对内存对齐的不影响
    • class有访问权限控制(如publicprivateprotected),而struct默认成员是public。但这些访问权限的设置不会影响内存对齐。无论成员是public还是private,编译器在进行内存布局时,只关注成员的数据类型和当前的对齐设置。
    • 例如,在一个class中,private成员和public成员在内存中的存储位置和填充方式是相同的,遵循相同的内存对齐规则。
  2. 继承对内存对齐的影响
    • 单一继承情况classstruct进行单一继承时,基类和派生类的成员在内存中的布局也会遵循内存对齐规则。派生类的内存布局通常是先存储基类的成员,然后是派生类自身的成员,在这个过程中,每一个成员(无论是基类的还是派生类的)都会根据其自身的数据类型和当前对齐设置进行存储,中间可能会插入填充字节。
    • 多重继承情况对于多重继承,情况会更加复杂。编译器需要按照一定的规则来安排多个基类成员和派生类成员的存储位置,并且保证每个成员都满足内存对齐要求。在这种情况下,不同编译器的实现可能会略有差异,但总体上还是遵循内存对齐的基本原则,尽量减少访问数据时的性能损失。
  3. 虚函数对内存对齐的影响(主要针对class)
    • 如果一个class包含虚函数,编译器会为该class添加一个虚函数表指针(通常是一个指针大小,在32位系统中为4字节,在64位系统中为64字节)。这个虚函数表指针的位置和类中的其他成员一样,也会遵循内存对齐规则。一般情况下,它会被放置在类对象内存布局的开头(在某些编译器实现中),并且会影响整个类对象的内存大小和布局。例如,一个只有虚函数的class对象,其大小至少是一个指针大小(用于存储虚函数表指针),并且会根据当前的对齐设置进行内存对齐。而struct如果没有类似虚函数的特性,就不会有这个虚函数表指针相关的内存布局变化。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

通过全球最前沿的技术解决视频拼接中时延带来的的应用缺陷,使得全景视频拼接能够真正得以大范围使用和推广的智慧地产开源了。

智慧地产视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。通过计算机视觉和…

推荐一款好用的postman替代工具2024

Apifox 是国内团队自主研发的 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台,是非常好的一款 postman 替代工具。 它通过一套系统、一份数据,解决多个系统之间的数据同步问题。只要定义好接口文档,接口调试、数据 Mock、接口…

java作业项目以及azkaban的操作

参考内容: azkaban简介及azkaban部署、原理和使用介绍 1.在azkaban创建project 2.上传flow文件和project文件的压缩包 flow文件内容: nodes:- name: Testtype: commandconfig:command: java -jar /data/job/mtm-job-0.0.1-SNAPSHOT.jar --spring.profiles.activ…

【重生之我要苦学C语言】深入理解指针5

深入理解指针5 回调函数 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数 回调函数不是由该函数的实现方直接调用,而是在特定的…

IOPaint模型部署教程

一、介绍 IOPaint是一款功能全面且强大的AI图像处理工具,它不仅免费开源,还由SOTA(State-of-the-Art,即最先进)AI模型驱动,为图像编辑和修复带来了前所未有的便利和高效。以下是对IOPaint的详细介绍&#…

吊打面试官系列:hashCode() 相同,equals() 就一定相等吗?

在编程的世界里,hashCode() 和 equals() 是一对形影不离的好兄弟。它们在Java中定义于Object类中,是每个Java对象都继承的两个方法。但是,如果你认为只要两个对象的hashCode()相同,它们的equals()就一定相等,那你就大错…

阿托伐他汀降脂疗效与安全性真实世界数据整理!

2024年9月,《中国医疗保险》杂志发布了题为《阿托伐他汀仿制药治疗高脂血症疗效与安全性的多中心回顾性队列研究》的重要研究结果。该研究由首都医科大学宣武医院牵头,联合上海交通大学医学院附属瑞金医院、吉林大学第一医院等10家国内顶尖三甲医院共同完…

深入剖析【C++继承】:单一继承与多重继承的策略与实践,解锁代码复用和多态的编程精髓,迈向高级C++编程之旅

​​​​​​​ 🌟个人主页:落叶 🌟当前专栏: C专栏 目录 继承的概念及定义 继承的概念 继承定义 定义格式 继承基类成员访问⽅式的变化 继承类模板 基类和派⽣类间的转换 继承中的作⽤域 隐藏规则 成员函数的隐藏 考察继承【作⽤…

“嵌入”在大语言模型中是解决把句子转换成向量表示的技术

上一篇:《人工智能是这样理解“情绪”的》 序言:这段话要优化吗?““嵌入”是一种将句子、单词或其他语言单位转换为向量表示的技术。这个向量通常位于高维空间中,它以一种能够表达相似性的方式编码出文本的含义或上下文。嵌入层…

操作系统——内存分区管理

本章主要讨论为什么要给内存进行划分和如何划分的问题。 为了给每一个进程都分配一个大小合适的内存块 以连续存储进程的程序和数据,使得各进程可以并发执行 目录 一、内存的划分方法 1、固定分区法 2、动态分区法 3、动态分区的数据管理结构 二、分区的分配与回…

ML 系列: 第 24 节 — 离散概率分布(泊松分布)

目录 一、说明 二、固定时间间隔示例 三、固定间隔的示例 四、泊松分布的主要特征 五、示例 5.1 平均客户数的计算: 5.2 用于计算和绘制泊松分布的 Python 代码: 一、说明 泊松概率分布是一种离散概率分布,它表示在固定的时间或空间间隔内发生…

【comfyui教程】如何用 ComfyUI 修复和上色老照片?详细教程让老照片焕发新生

前言 如何用 ComfyUI 修复和上色老照片?详细教程让老照片焕发新生 老照片承载着无数回忆,可时光不饶人,随着岁月流逝,它们渐渐变得模糊、泛黄,甚至出现了褪色、裂痕。对于想要留住这份珍贵记忆的人来说,修…

ThinkServer SR658H V2服务器BMC做raid与装系统

目录 前提准备 一. 给磁盘做raid 二. 安装系统 前提准备 磁盘和系统BMC地址都已经准备好,可正常使用。 例: 设备BMC地址:10.99.240.196 一. 给磁盘做raid 要求: 1. 将两个894G的磁盘做成raid1 2. 将两块14902G的磁盘各自做…

BUUCTF pwn2_sctf_2016 int 0x80方法

本文目的 BUUCTF的PWN的第一页的pwn2_sctf_2016的libc不适用辣,但网上一搜全是libc 然后怎么办嘞,都明摆着有个int 0x80,当然是用啊 所以水一篇 早上中午晚上好 老三样,下载程序,打开ida,拖进去 一眼好几…

如何构建一个功能强大的低代码平台网站?关键步骤与技巧全解析

随着数字化转型的加速,企业对敏捷开发和快速迭代的需求越来越迫切。低代码平台应运而生,成为连接业务需求和技术实现的重要桥梁。低代码平台不仅能够大幅降低技术门槛,还能够通过可视化界面和预配置组件简化开发流程,帮助企业快速…

Unity图形学之Shader2.0 模板测试

1.模版测试:符合条件的 通过 不符合条件的 像素 丢弃 比较公式: if((referenceValue&readMask) comparisonFunction (stencilBufferValue&readMask)) 通过像素 else 抛弃…

RK3588 快速上手

1、资料介绍 我的开发板是临滴科技的LKD3588,相关的官网上都可以找到,我这里给大家一个网盘链接 LKD3588-开发板(公开资料) https://pan.baidu.com/s/1snYcWY-S4rLMCE_3nGlHrw?pwd3588 LKD3588-开发板(保密资料&…

STM32完全学习——点亮LED灯

一、寄存器描述 首先我们知道STM32对外设的操作,是靠对寄存器的设置来完成的。因此我们想要点亮LED灯,就需要知道端口的控制寄存器,然后给寄存器设置不同的值就可以让端口来输出0或1,首先我这里使用的是GPIOA这个端口的0-8位来做…

【Python】如何使用Python-Tkinter打造炫酷动态心形动画 !保姆级教程

文章目录 教程:从零开始,逐步实现动态心形动画环境准备第一步:导入必要的模块第二步:定义画布参数第三步:定义心形生成函数第四步:实现点的散布与收缩第五步:定义曲线函数第六步:创建…

基于SSM的“家政预约管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“家政预约管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 家政预约管理系统功能结构图 系统首页界面 用户注册界面 家政…