结构体字节对齐问题

2023-11-14


一、结构体必知知识

1、结构体内成员按照声明顺序存储,第一个成员地址和整个结构体地址相同(第一个数据成员放在offset为0的地方)。

2、结构体中的某个成员地址为结构体变量的基址加上结构体变量在结构体中的偏移量。

二、结构体字节对齐有什么用?

1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2)性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。(为何需要进行两次的访问,见:https://blog.csdn.net/chen895281773/article/details/9567337)

引自:https://www.nowcoder.com/ta/review-c/review?tpId=22&tqId=31400&query=%E7%BB%93%E6%9E%84%E4%BD%93&asc=true&order=&page=1

三、如何进行内存对齐?

1.对齐规则:按结构体中最长类型字节为单位

以下代码为例:

#include <iostream>
using namespace std;

struct {
	int a;
	double b;
	short c;
}A;
//对齐单位为8个字节

int main() {
	 
	cout << "结构体变量A的大小:\t" << sizeof(A) << endl;

	return 0;
}

程序输出:
在这里插入图片描述
int占4个字节,double占8个字节,short占2个字节,最大为8个字节,因此对齐单位为8个字节。以8个字节为单位设置好内存分布。

对于int a:
4 * 0 = 0,offeset = 0的位置是空的,故0~3存放a。

对于double b:
8 * 0 = 0,offset = 0的位置存放了a
8 * 1 = 8, offset = 8位置为空,可以存放,故8~15
(4~7位置用来对齐,这里以*补充)

对于short c :
2 * 0 = 0,offset = 0存放a
2 * 1 = 2,存放a

2 * 4 = 8,offset = 8存放b

2 * 8 = 16,offset = 16为空,可以存放,16~17存放c,18 ~23用来对齐。
即:
在这里插入图片描述

注:改变结构体中成员的声明顺序可能会导致结构体变量的布局,如调换int a和double b的声明顺序:

struct {
	double b;
	int a;
	short c;
}A;

程序输出:
在这里插入图片描述
分析:对齐单位为8个字节
double b:
8 * 0 = 0,0~7存放b

int a:
4 * 0 = 0,

4 * 2 = 8,8~11c存放a

short c :
2 * 0 = 0,

2 * 6 = 12,12~13存放c,14 ~15补充*

即:
在这里插入图片描述

2.结构体嵌套的情况

字节对齐单位:按本结构体中最长类型字节与嵌套结构体中最长类型字节的较大值为对齐单位。

嵌套结构体部分存放规则:起点以下一行字节对齐单元算起。

struct myA{
	int a;
	double b;
	short c;
}A;

struct {
	char e[2];
	int f;
	double g;
	short h;
	struct myA i;
}B;
//对齐单位8个字节

程序输出:
在这里插入图片描述

分析:
1)对齐单位:struct B中最长类型字节为8个字节,嵌套结构体struct A中最长类型字节为8个字节,取两者最大值,则对齐单位为8个字节。

2)结构体B中struct A之前的部分按照之前的对齐规则处理。

char e[2]: 0~1
int f: 4~7
double g: 8~15
short h: 16~17

计算嵌套结构体以下一行字节对齐单元算起(18~23补*):
int a: 24~27
double b: 32~39
short c: 40~41

即:

在这里插入图片描述

3.存在指定字节对齐单位的情况(#pragma pack)

字节对齐单位:按结构体中最长类型字节和指定的对齐单位之间的较小值为对齐单位。

#pragma pack指定的数值必须为2^n。

#pragma pack(2) //指定对齐单位为2个字节
struct {
	int a;
	char b;
	short c;
	char d;
}A;
//最终对齐单位为2个字节

程序输出:
在这里插入图片描述
分析:
指定对齐单位为2个字节,结构体中最长类型字节为4个字节,取较小值2个字节为对齐单位。

int a: 0~1 和2~3
char b: 4
short c: 6~7
char d: 8
即:
在这里插入图片描述

如何进行结构体对齐部分总结自黑马程序员C语言课程,有兴趣的话可以看一下课程:https://www.bilibili.com/video/BV1GW411n7FZ?p=113

总结

结构体对齐是C/C++学习中的一个重点问题,结构体对齐有什么用处,如何进行结构体对齐也是面试中的一个经典考点,本文主要介绍这两个问题。这也是本人第一次发表的博客,其中不对的地方希望多多指正,谢谢~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构体字节对齐问题 的相关文章

  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 为什么我不能用 `= delete;` 声明纯虚函数?

    Intro 纯虚函数使用通用语法声明 virtual f 0 然而 自 c 11 以来 有一种方法可以显式地传达non existence 特殊 成员函数的 Mystruct delete eg default constructor Q
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • 对齐 GridView 中的行值

    我需要在 asp net 3 5 中右对齐 gridview 列中的值 我怎样才能做到这一点
  • 从多个类访问串行端口

    我正在尝试使用串行端口在 arduino 和 C 程序之间进行通信 我对 C 编程有点陌生 该程序有多种用户控制形式 每一个都需要访问串口来发送数据 我需要做的就是从每个类的主窗体中写入串行端口 我了解如何设置和写入串行端口 这是我的 Fo
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 实例化 Microsoft.Office.Interop.Excel.Application 对象时出现错误:800700c1

    实例化 Microsoft Office Interop Excel Application 以从 winforms 应用程序生成 Excel 时 出现以下错误 这之前是有效的 但突然间它停止工作了 尽管代码和 Excel 版本没有变化 我
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检

随机推荐

  • VNC+FileZilla使用

    VNC FileZilla使用 VNC FileZilla 在使用树莓派和Jetson Nano开发板时 因为没买显示器 所以只能通过VNC用电脑屏幕显示 但从电脑传文件到开发板上诸多不便 于是配合FileZilla使用 使文件传输变得非常
  • Mybatis-SQL注入

    测试sql注入攻击 sql会睡眠5秒才返回 Test public void test02 QueryWrapper
  • 菜鸟学习nginx之HTTP请求处理(2)

    在上一篇介绍了Nginx定义的11个阶段 本篇将深入介绍Nginx是如何处理HTTP请求的 一 ngx http process request 处理HTTP请求 param r HTTP请求 当成功接收到请求行和Header时 就可以处理
  • Java类加载机制与Tomcat类加载器架构

    Java类加载机制 类加载器 虚拟机设计团队把类加载阶段中的 通过一个类的全限定名来获取描述此类的二进制字节流 这个动作放到Java虚拟机外部去实现 以便让应用程序自己决定如何去获取所需要的类 实现这个动作的代码模块称为 类加载器 类加载器
  • Unity界面入门教程

    Unity界面入门教程 本教程将介绍Unity的用户界面 GUI 学时 一小时 作者 Graham McAllister 译者 威阿2009 04 06 目录 1 教程目的 2 屏幕布局 3 查找游戏对象 4 创建游戏对象 5 场景视图导航
  • java代码分层、每层业务、为何分层

    SpringBoot 分为四层 controller层 service层 dao层 model层 controller层 控制层 存放各种控制器 来提供数据或者返回界面 实现对Get和Post的相应 用于前后端交互 service层和前端通
  • led灯条维修_浅谈LED路灯驱动电源设计方案--海光照明

    LED路灯是LED照明中一个很重要应用 在节能省电的前提下 LED路灯取代传统路灯的趋势越来越明显 市面上 LED路灯电源的设计有很多种 早期的设计比较重视低成本的追求 到近期 共识渐渐形成 高效率及高可靠性才是最重要的 下面针对几种不同L
  • Python_OpenCV调用摄像头完成人脸识别

    核心是找到 haarcascade frontalface default xml 这个文件 一般来说下载了OpenCV库都有 直接去自己电脑找就行了 import cv2 调用模型库文件 face cascade cv2 CascadeC
  • docker制作镜像

    从 rootfs 压缩包导入 格式 docker import 选项 lt 文件 gt lt 仓库名 gt lt 标签 gt 压缩包可以是本地文件 远程 Web 文件 甚至是从标准输入中得到 压缩包将会在镜像 目录展开 并直接作为镜像第一层
  • 别让“低效沟通”成为企业的成本之痛

    管理学家曾说过 企业管理行为与沟通密不可分 80 的管理成本都与沟通有关 如今 有效沟通 在主流的企业管理价值倡导中越来越被广泛提及 渐渐成为每一个管理者必备的素质要求 其中最直接的体现就是各大商学院已经把它纳入核心课程体系中去 一 有效沟
  • WildFly 报错 java.lang.NoClassDefFoundError

    在eclipse上WildFly部署项目后 启动一直报错java lang NoClassDefFoundError 功夫不负有心人 终于解决 解决方案 查了网上很多资料 有说环境变量配置不对的 有说改wildfly 9 0 1 Final
  • Devops环境准备

    系统准备 https mirrors aliyun com centos 7 isos x86 64 安装Minimal 版本即可 root root 安装ifconfig yum install net tools x86 64 安装JD
  • 网络:网络协议基本原理

    引入 进程间通信 其实是通过内核的数据结构完成的 主要用于在一台linux上两个进程之间的通信 但是 一旦超出一台机器的范畴 我们就需要一种跨进程的通信机制 一台机器将自己想要表达的内容 按照某种约定好的格式发送出去 当另一条机器收到这些信
  • 八家校招公司的面试问题总结

    八家校招公司的面试问题总结 阿里 1 String s abc s存储在哪个区域 2 HashMap实现原理 ConcurrentHashMap实现原理 3 红黑树 为什么允许局部不平衡 4 TCP UDP区别 为什么可靠和不可靠 5 一次
  • Linux之Samba服务配置与管理

    Linux之Samba服务配置与管理 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件 由服务器及客户端程序构成 SMB Server Messages Block 信息服务块 是一种在局域网上共享文件和打印机的一种通信
  • Jetpack Compose — 让Composable具备生命周期感知

    Jetpack Compose 让Composable具备生命周期感知 我们将研究不同的方法来实现可组合 Composable 的生命周期感知 我们还将了解可组合生命周期和视图 View 生命周期之间的区别 我们将逐步探索不同的解决方案 以
  • 开源中国-仿写代码

    开源中国源码 div class page div
  • 微信小程序获取用户唯一标识openid

    相关知识 微信小程序 spring boot 一 步骤 1 获得的用户登录凭证code 有效期五分钟 2 发送参数code至后端 3 通过code获取openid 二 实现 1 获取code 接口 wx login 接口地址 https d
  • 工作中碰到的git问题

    这是平时工作中遇到的问题 百度结果很多 觉得有用的在此作个记录 一 git解决代码冲突 拉取时冲突 1 将本地的修改提交到本地库 2 执行命令 1 git pull origin master 将远程库代码拉取并合并到本地库 2 git p
  • 结构体字节对齐问题

    文章目录 一 结构体必知知识 二 结构体字节对齐有什么用 三 如何进行内存对齐 1 对齐规则 按结构体中最长类型字节为单位 2 结构体嵌套的情况 3 存在指定字节对齐单位的情况 pragma pack 总结 一 结构体必知知识 1 结构体内