结构体内存对齐

结构体内存对齐的规则

  • 第一个成员在结构体对象的首地址处。
  • 其他成员变量要对齐到对齐数的整数倍。
  • 结构体对象的总大小是最大对齐数的整数倍。
  • 如果结构体内嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处。结构体整个大小就是最大对齐数的整数倍。

对齐数该结构体成员变量自身的大小与编译器默认的一个对齐数的较小值就是对齐数

vs系列的编译器默认对齐数是8,不是所有编译器都有默认对齐数,当编译器没有默认对齐数的时候,成员变量的大小就是该成员的对齐数。

struct S
{
	double d;
	char c;
	int i;
};

比如上面结构体S,在vs编译器下,默认对齐数是8。

  • d成员的大小是8,默认对齐数是8,较小值是8。最终对齐数就是8
  • c成员的大小是1,默认对齐数是8,较小值是1。最终对齐数就是1
  • i成员的大小是4,默认对齐数是8,较小值是4。最终对齐数就是4

在整个结构体对象内存中。
d是第一个成员,对齐到结构体对象的首地址即可。c要对齐到1的整数倍,i要对齐到4的整数倍。
图解:

image.png

  • d从起始地址占8个字节即可,c对齐1的整数倍,占1个字节即可。i要对齐到4的整数倍,占4个字节。

  • 然后确定整个结构体对象的总大小。最大对齐数的整数倍,也就是8的整数倍。[0,15]一共占用了16个字节,是8的整数倍。所以整个结构体对象S的大小就是16字节。

  • 在vs下创建一个S对象,一共要用占用16字节,浪费了3字节。

当有嵌套的时候。

struct S
{
	double d;
	char c;
	int i;
};
struct SS
{
    struct S a;
    char b;
}
  • SS的成员a大小是16,默认对齐数是8,较小值是8,最终对齐数是8
  • 成员b的大小是1,默认对齐数是1,较小值是1。最终对齐数是1

a是第一个成员大小,占16个字节即可。b对齐到1的整数倍,也就是16。最终整个SS对象大小是8的整数倍,[0,16]是17个字节,所以SS对象大小是24字节。

为什么存在内存对齐?

  • 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常。
    比如,当一个平台要取一个整型数据时只能在地址为4的倍数的位置取得,那么这时就需要内存对齐,否则无法访问到该整型数据。
  • 性能原因:  数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐内存,处理器需要作两次内存访问;而对齐的内存访问仅需一次。

结构体设计的技巧

在我们设计结构体的时候,如果结构体成员的顺序设计得合理的话,是可以避免不必要的内存消耗的。
两个结构体的成员变量相同,但是成员变量的顺序不同,可能就会出现结构体的大小不同的情况:

struct S1
{
	char a;
	char b;
	int c;
};//结构体1
struct S2
{
	char a;
	int c;
	char b;
};//结构体2

两个同样的结构体1和2,由于成员变量的顺序不一样,结构体S1的大小是8,s2的大小是12。
可以见得,结构体成员变量的顺序不同,可能会造成内存不必要的损失。将占用空间小的成员尽量集中在一起,可以有效地避免内存不必要的浪费。

修改默认对齐数

要修改编译器的默认对齐数,我们需要借助于以下预处理命令:

#pragma pack(4)//设置默认对齐数为4
#pragma pack()//取消设置的默认对齐数,还原为默认

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JS高级 - Promise使用方法详解

目录 一、什么是Promise 1.1 Promise的三种状态 二、Promise 基本用法 2.1 Promise基本使用 2.2 Promise使用时传参 2.3 Promise 链式调用 2.4 链式调用注意事项 三、Promise内置方法 3.1 Promise.all() 3.2 Promise.race() 3.3 Promise.allSettled() 3.4 Promise.…

1688商家自曝流量暴涨技巧!7天起店,仅需4步神操作!

经常有人问我1688,7天怎么起店?根据之前的一些经验分享一下,大概7天就能做到4位数以下的展现量,4步轻松完成。 新运营课堂第一步,进入卖家工作台,点击商品,查看单品被收藏次数及被加购次数&…

C++--浅拷贝和深拷贝

浅拷贝和深拷贝 1.浅拷贝 浅拷贝,多个指针指向同一段内存,出现一处指针修改数据,其它指针的数据也发生改变。 1.1 面向过程的浅拷贝(C方式) 如下代码: //下面程序,从键盘获取4个字符串,然后输出到屏幕 int main() {char buf[100];char* strArr[4];//长度为4的字符指针数组…

Unity面向切面编程

一直说面向AOP(切面)编程,好久直接专门扒出理论、代码学习过。最近因为某些原因😭还得再学学造火箭的技术。 废话不多说,啥是AOP呢?这里我就不班门弄斧了,网上资料一大堆,解释的肯定…

广东海洋大学成功部署(泰迪智能科技)大数据人工智能实验室建设

广东海洋大学简称广东海大,坐落于广东省湛江市,是国家海洋局与广东省人民政府共建的省属重点建设大学、广东省高水平大学重点学科建设高校、粤港澳高校联盟成员 ,入选卓越农林人才教育培养计划,是教育部本科教学水平评估优秀院校。…

【SQL】数据库SQL语句

1、主键 主键值唯一,不可修改,不能为空,删除不能重用 2、数据类型(常用) char int float date timestamp 3、select select * from data; select xx,xxx from data;//取部分行 select * from data limit 100; //限…

msyql中的四大日志

日志 错误日志二进制日志作用日志格式日志查看日志删除 查询日志慢查询日志 错误日志 错误日志是MySQL中最重要的日志之一,它记录了当MySQL启动和停止时,以及服务器子啊运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时…

angular node版本问题导致运行出错时应该怎么处理

如下图所示: 处理方式如下: package.json中start跟build中添加:SET NODE_OPTIONS--openssl-legacy-provider即可

SSRF+Redis未授权getshell

SSRFRedis未授权getshell 1.前言 当一个网站具有ssrf漏洞,如果没有一些过滤措施,比如没过滤file协议,gophere协议,dict等协议,就会导致无法访问的内网服务器信息泄露,甚至可以让攻击者拿下内网服务器权限 …

pixhawk控制板的ArduPilot固件编译

0. 环境 - ubuntu18(依赖python2和pip,建议直接ubuntu18不用最新的) - pixhawk 2.4.8 - pixhawk 4 1. 获取源码 # 安装git sudo apt install git # 获取源码 cd ~/work git clone --recurse-submodules https://github.com/ArduPilot/a…

腾讯AI Lab:“自我对抗”提升大模型的推理能力

本文介绍了一种名为“对抗性禁忌”(Adversarial Taboo)的双人对抗语言游戏,用于通过自我对弈提升大型语言模型的推理能力。 👉 具体的流程 1️⃣ 游戏设计:在这个游戏中,有两个角色:攻击者和防守…

VsCode调试远程服务器上面的Docker容器

第一步 VsCode 连接ssh 下载安装VsCode(Visual Studio Code),首次安装会提示你安装Chinese(Simplified)中文简体,安装完后重新打开就是汉化界面了。在左边侧边栏找到扩展选项,然后安装Remote Development插件,里面包含了Remote S…

糖尿病可能是一团虚火,肝肾同源,肝阴不足。

其实对于很多的糖尿病患者来说,他的问题本质可能是一团虚火,就拿前段时间我的门诊一个患者为例,之前患有高血压,总是眩晕烦躁,常常失眠,大概近四个月出现多饮、多尿怎么喝水也不解渴,经过检查确…

每日一题---OJ题: 链表的回文结构

片头 嗨! 小伙伴们,大家好! 今天我们来一起学习这道OJ题--- 链表的回文结构 嗯...这道题好像不是很难,我们来分析分析 举个例子: 我们可以看到,上图中的两个链表都是回文结构: 即链表的回文结构是指一个链表中的结点值从前往后读和从后往前读都是一样的结构。也就是说&#xf…

春秋云境:CVE-2022-32991[漏洞复现]

从CVE官网查询该漏洞相关信息 该漏洞是由于welcome.php中的eid参数包含了SQL注入漏洞 则我们的目标就在于寻找welcome.php地址以及相关的可注入eid参数 开启靶机 先在页面正常注册、登录一个账号。密码随便填 进入了home目录,这里有三个话题可以选择开启 随便选…

word批量修改表格样式

利用宏,批量选中表格,然后利用段落和表设计来操作。 利用宏,批量选中表格,参考百度安全验证段落,表格里面的内容有空格,应该是有缩进,在段落中去掉缩进,即缩进-特殊,选择…

Next.js 14 App Router引入 farmer-motion 初始化异常解决,顺带学点知识

前言 farmer-motion 是一个非常好用的动画库,当然用来做组件切换和路由切换过渡更不在话下。 记录一下,Next.js 14 App Router 下引入初始化异常的解决姿势,顺带扯一下 next.js 的知识点; 问题 过渡组件代码 我们拿 farmer-m…

https证书是什么,怎么申请

https证书的名称有很多,其本名是SSL/TLS数字证书,本意是实现https访问的证书,故而很多人会称之为https证书,又因为其需要部署于域名服务器之上,所以也有人称之为域名证书。 所以https证书又名SSL证书、域名证书等。 h…

SPN的相关利用(上)

什么是SPN 服务主体名称(SPN)是服务实例,可以理解为一个服务,比如mssql,http等等的唯一标识符。如果在整个林或域中的计算机上安装多个服务实例,则每个实例都必须具有自己的 SPN,Kerberos 身份验证使用 SPN 将服务实例与服务登录…

深入理解 pytest Fixture 方法及其应用

当涉及到编写自动化测试时,测试框架和工具的选择对于测试用例的设计和执行非常重要。在Python 中,pytest是一种广泛使用的测试框架,它提供了丰富的功能和灵活的扩展性。其中一个很有用的功 能是fixture方法,它允许我们初始化测试环…