c/c++--字节对齐(byte alignment)

1. 默认字节对齐

  • 在所有结构体成员的字节长度都没有超出操作系统基本字节单位(32位操作系统是4,64位操作系统是8)的情况下
    按照结构体中字节最大的变量长度来对齐;
  • 若结构体中某个变量字节超出操作系统基本字节单位
    那么就按照系统字节单位来对齐

注意:
并不是32位就直接按照4个字节对齐,64位就按照8个字节对齐。

2. 为什么存在字节对齐

2.1 了解 CPU 一次读取内存数

CPU 一次能读取多少内存要看数据总线是多少位

  • 如果是16位,则一次只能读取 2 个字节
  • 如果是32位,则可以读取 4 个字节,并且 CPU 不能跨内存区间访问

例子:

假设有这样一个结构体如下:

struct st3
{char a;int b;
};
//在32位系统下,它就应该是8个字节的。

假设地址空间是类似下面这样的:
在这里插入图片描述

  • 在没有字节对齐的情况下

    1. 变量 a 就是占用了 0x00000001 这一个字节,而变量b则是占用了 0x00000002~0x000000005 这四个字节
    2. 此时 cpu 如果想从内存中读取变量 b,首先要从变量 b 的开始地址 0x00000002读到 0x0000004,然后再读取一次 0x00000005 这个字节,相当于读一个 int,cpu 从内存读取了两次
  • 如果进行字节对齐的话

    1. 变量 a 还是占用了 0x00000001 这一个字节,而变量 b 则是占用了 0x00000005~0x00000008 这四个字节
    2. 此时 cpu 要读取变量 b 的话,就直接一次性从 0x00000005 读到 0x00000008 ,就一次全部读取出来了。

总结:

  • 字节对齐的根本原因其实在于 cpu 读取内存的效率问题,对齐以后,cpu读取内存的效率会更快。
  • 对齐的时候 0x00000002~0x00000004 这三个字节是浪费的,所以字节对齐实际上也有那么点以空间换时间的意思,具体写代码的时候怎么选择,其实是看个人的。

3. 编码时手动设置对齐

两种。

3.1 代码里添加预编译标识 pragma pack(n)

3.1.1 用法

  • 使用预编译指令 #pragma pack (n) 来告诉编译器,使用我们指定的对齐值来取代缺省的。
  • 对齐的算法: 随编译器变化
//用法如下
#pragma pack(n)//表示它后面的代码都按照n个字节对齐
struct st3
{char a;int b;
};
#pragma pack()//取消按照n个字节对齐,是对#pragma pack(n)的一个反向操作

3.1.2 例子

#include <stdio.h>#pragma pack(1)//表示它后面的代码都按照n个字节对齐
struct st3
{char a;int b;
};
#pragma pack()//取消按照n个字节对齐,是对#pragma pack(n)的一个反向操作#pragma pack(2)//表示它后面的代码都按照n个字节对齐
struct st4
{char a;int b;
};
#pragma pack()//取消按照n个字节对齐,是对#pragma pack(n)的一个反向操作int main()
{printf("%d\n",sizeof(struct st3) );printf("%d\n",sizeof(struct st4) );return 0;
}

在这里插入图片描述

3.2 定义结构体时指定__attribute__((packed))

3.2.1 用法

  • __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法。这个功能是跟操作系统没关系跟编译器有关.
//用法如下
struct bbb
{char a;int b;
}__attribute__((packed));//直接按照实际占用字节来对齐,其实就是相当于按照1个字节对齐了
//这里计算sizeof(st3)=5

3.2.2 例子

#include <stdio.h>struct st3
{char a;int b;
}__attribute__((packed));struct __attribute__((packed)) st4
{int b;char a;
};int main()
{printf("%d\n",sizeof(struct st3) );printf("%d\n",sizeof(struct st4) );return 0;
}

在这里插入图片描述

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

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

相关文章

视频监控系统/安防视频平台EasyCVR广场视频细节优化

安防视频监控系统/视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频汇聚平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;可实现视频监控直播、视频轮播、…

【Python 零基础入门 】安装 环境配置

【Python 零基础入门 】第一课 安装 & 环境配置 Python 零基础入门 第一课 安装 & 环境配置Python 的历史Python 的前景安装了解你的操作系统Python 安装环境配置 PyCharm 安装第一个程序 Python 零基础入门 第一课 安装 & 环境配置 在当今的技术时代, 编程语言正…

微信小程序/vue3/uview-plus form兜底校验

效果图 代码 <template><u-form :model"form" ref"formRole" :rules"rules"><u-form-item prop"nickname"><u-input v-model"form.nickname" placeholder"姓名" border"none" /&…

没用的知识增加了,尝试用文心实现褒义词贬义词快速分类

尝试用文心实现褒义词贬义词快速分类 一、我的需求二、项目环境搭建千帆SDK安装及使用流程 三、项目实现过程创建应用获取签名调用接口计算向量积总结 百度世界大会将于10月17日在北京首钢园举办&#xff0c;今天进入倒计时五天了。通过官方渠道的信息了解到&#xff0c;这次是…

Web后端开发登录校验及JWT令牌,过滤器,拦截器详解

如果用户名正确则成功进入 登录功能 代码 Controller Service Mapper 结果 若登录成功结果如下: 如果登录失败,结果如下 登录校验 为什么需要登录校验 有时再未登录情况下, 我们也可以直接访问部门管理, 员工管理等功能 因此我们需要一个登录校验操作, 只有确认用户登录…

【Debian】报错:su: Authentication failure

项目场景&#xff1a; 今天我重新刷了一个debian系统。 系统版本&#xff1a; # 查看系统版本 lsb_release -a 我的系统版本&#xff1a; No LSB modules are available. Distributor ID&#xff1a;Debian Description: Debian GNU/Linux 12 &#xff08;bookworm&#xff…

优雅而高效的JavaScript——箭头函数

&#x1f917;博主&#xff1a;小猫娃来啦 &#x1f917;文章核心&#xff1a;优雅而高效的JavaScript——箭头函数 文章目录 前言箭头函数的基本语法和特点箭头函数的语法箭头函数的词法绑定特性箭头函数的this值箭头函数无法使用arguments对象 箭头函数与传统函数的比较箭头函…

每年高考时间是几月几号 高考开始时间

高考是高中生最重要的一个阶段&#xff0c;甚至影响着很多学生的未来&#xff0c;相信大家都很关注高考的具体时间是什么时候&#xff0c;本次将详细给您介绍高考的具体开始时间以及结束时间。 每年高考的时间都是6月7日开始&#xff0c;一共持续三天时间左右&#xff0c;但是…

身份证号码,格式校验:@IdCard(自定义注解)

目标 自定义一个用于校验 身份证号码 格式的注解IdCard&#xff0c;能够和现有的 Validation 兼容&#xff0c;使用方式和其他校验注解保持一致&#xff08;使用 Valid 注解接口参数&#xff09;。 校验逻辑 有效格式 符合国家标准。 公民身份号码按照GB11643&#xff0d;…

竞赛选题 深度学习+opencv+python实现车道线检测 - 自动驾驶

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…

印度网络安全:威胁与应对

随着今年过半&#xff0c;我们需要评估并了解不断崛起的网络威胁复杂性&#xff0c;这些威胁正在改变我们的数字景观。 从破坏性的网络钓鱼攻击到利用人工智能的威胁&#xff0c;印度的网络犯罪正在升级。然而&#xff0c;在高调的数据泄露事件风暴中&#xff0c;我们看到了政…

游戏反虚拟机检测方案

近年来&#xff0c;游戏市场高速发展&#xff0c;随之而来的还有图谋利益的游戏黑产。在利益吸引下&#xff0c;游戏黑产扩张迅猛&#xff0c;攻击趋势呈现出角度多样化的特点。 在这一趋势下&#xff0c;游戏安全防护的检测覆盖率显得尤为重要。如果游戏在某一环节出现被绕过…

Linux系统卡顿处理记录(Debian)

问题现象描述 现象linux操作系统卡顿&#xff08;就是很慢&#xff09;&#xff0c;但是系统任然能够使用。 文章一步步的排查并且定位问题。 排查步骤 1. 使用top命令查看CPU是否占用过高。&#xff08;未发现&#xff09;排除问题 2. 使用df -h查看硬盘是否被占满。&#…

浏览器唤起钉钉 各项功能

浏览器唤起钉钉对应人员聊天 文档地址 https://open.dingtalk.com/document/client/unified-routing-protocol 唤起聊天 不过只能唤起叮叮的名片 id为叮叮号 <a href"dingtalk://dingtalkclient/action/sendmsg?dingtalk_id{id}"></a>id&#xff1a; …

Spark 9:Spark 新特性

Spark 3.0 新特性 Adaptive Query Execution 自适应查询(SparkSQL) 由于缺乏或者不准确的数据统计信息(元数据)和对成本的错误估算(执行计划调度)导致生成的初始执行计划不理想&#xff0c;在Spark3.x版本提供Adaptive Query Execution自适应查询技术&#xff0c;通过在”运行…

vite+vue3+ts中使用require.context | 报错require is not defined | 获取文件夹中的文件名

vitevue3ts中使用require.context|报错require is not defined|获取文件夹中的文件名 目录 vitevue3ts中使用require.context|报错require is not defined|获取文件夹中的文件名一、问题背景二、报错原因三、解决方法 一、问题背景 如题在vitevue3ts中使用required.context时报…

《UnityShader入门精要》学习1

读者可以在开源网站github&#xff08;https://github.com/candycat1992/Unity_Shaders_Book&#xff09;上下载本书的源代码。 第二章 渲染流水线 渲染流水线的最终目的在于生成或者说是渲染一张二维纹理&#xff0c;即我们在电脑屏幕上看到的所有效果&#xff0c;它的输入是…

【网络安全】「漏洞原理」(二)SQL 注入漏洞之理论讲解

前言 严正声明&#xff1a;本博文所讨论的技术仅用于研究学习&#xff0c;旨在增强读者的信息安全意识&#xff0c;提高信息安全防护技能&#xff0c;严禁用于非法活动。任何个人、团体、组织不得用于非法目的&#xff0c;违法犯罪必将受到法律的严厉制裁。 【点击此处即可获…

发送消息时序图

内窥镜消息队列发送消息原理 目的 有一个多线程的Java应用程序&#xff0c;使用消息队列来处理命令 时序图 startumlactor User participant "sendCmdWhiteBalance()" as Controller participant CommandConsumer participant MessageQueueUser -> Controller:…

【数据库】Sql Server数据迁移,处理自增字段赋值

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 在实际项目开发中&#xff0c;如果遇到高版本导入到低版本&#xff0c;或者低版本转高版本&#xff0c;那么就会出现版本不兼容无法导入&#xff0c;此时通过程序遍历创建表和添加数据方式…