【C语言】结构体内存对齐机制详解

C语言结构体对齐,超详细,超易懂 结构体对齐规则 结构体的第一个成员总是存放在结构体变量开辟的空间的起始地址 其它成员变量要存储在一个名叫对齐数的整数倍的地址 结构体总大小为最大对齐数的整数倍,结构体内每一个变量都会产生一个对齐数,取其最大的对齐数 如果是嵌套结构体,那么嵌套的结构体存储在嵌套结构体的成员的最大对齐数的整数倍地址处,包含嵌套结构体的结构体大小为自己成员的对齐数和嵌套结构体的成员的对齐数的最大对齐数的整数倍 阅读详情

一、前言

在讲解结构体内存对齐机制之前,我们先来看1个例子:

typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;

int main(){
    STU student1;
    printf("%d\n",sizeof(student1));//  打印结构体变量所占内存长度
    return 0;
}

以上代码示例中定义了1个结构体student1,包含5个不同数据类型的成员,分别占用内存空间:
char sex:1 Byte
int id:4 Byte
char name[20]:20 Byte
float score:4 Byte
char addr[30]:30 Byte
根据结构体特性,结构体变量所占内存长度等于其各成员所占内存长度之和,因此这里打印的sizeof(student1)是否等于1+4+20+4+30=59呢?运行程序后结果如下:

size of student1: 64

为什么这里结构体变量student1所占内存长度是64而不是59呢?因为有结构体内存对齐机制的存在。这是很多新手程序猿很容易走进的一个误区,接下来我们一起来了解结构体对齐机制。

二、结构体内存对齐规则

  1. 结构体第一个成员的地址即为该结构体变量的地址。
  2. 结构体成员内存对齐时,其存放的内存单元大小为min{有效对齐值,指定对齐值}的最小整数倍。
    注意:
    自身对齐值: 结构体变量里每个成员自身所占内存大小
    指定对齐值: 使用宏定义#pragma pack(N) 其中N的值即为指定对齐值。N必须是2的幂次方,例如:1,2,4,8等,如果没有使用宏定义指定对齐值,则指定对齐值取决于操作系统位数,32位操作系统默认指定对齐值为4,64位操作系统默认指定对齐值为8。
    有效对齐值: 有效对齐值为min{自身对齐值,指定对齐值}。
  3. 结构体总占用内存大小为min{成员最大自身对齐值,指定对齐值}的整数倍。

三、实例解析

以下示例代码均在64位Windows操作系统下运行
1、使用默认指定对齐值
使用文章前言的代码分析:

#include <stdio.h>

typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;

int main(){
    STU student1;
    printf("size of student1: %d\n",sizeof(student1));    //  打印结构体变量所占内存长度
    return 0;
}
成员自身对齐值指定对齐值有效对齐值
sex18min{1,8}
id48min{4,8}
name[20]18min{1,8}
score48min{4,8}
addr[30]18min{1,8}

结构体总体对齐时,应按照成员自身对齐值的最大值的整数倍对齐,这里程序在没有宏定义指定默认对齐值的情况下,对齐值就应该是min{4,8},也就是4字节,这种情况下,该结构体每一个成员开辟的存储空间都为4字节。

成员实际占用内存大小系统开辟内存空间大小
sex14
id44
name[20]2020
score44
addr[30]3032

在这里插入图片描述

成员id、name[20]、score实际占用内存大小刚好是对齐值4的整数倍,而成员sex则需要开辟4字节空间,实际只占用1字节,剩余3字节未使用;成员addr[30]需要开辟32字节空间,实际使用30字节,剩余2字节未使用。因此打印结构体变量student1所占内存大小为64字节。

2、修改默认指定对齐值
在上述示例基础之上修改默认指定对齐值:

#include <stdio.h>
#pragma pack(1) //  指定默认对齐值为1
typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;
#pragma pack()  //  取消修改对齐值
int main(){
    STU student1;
    printf("size of student1: %d\n",sizeof(student1));    //  打印结构体变量所占内存长度
    return 0;
}

此时程序输出结果为:

size of student1: 59

以上代码使用#pragma pack(1) 将默认指定对齐值修改为1,那么结构体成员将会按照1字节做内存对齐。

成员实际占用内存大小系统开辟内存空间大小
sex11
id44
name[20]2020
score44
addr[30]3030

此时打印结构体变量student1所占内存长度就为59。

如果将默认指定对齐值修改为2呢?

#include <stdio.h>
#pragma pack(2) //  指定默认对齐值为1
typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;
#pragma pack()  //  取消修改对齐值
int main(){
    STU student1;
    printf("size of student1: %d\n",sizeof(student1));    //  打印结构体变量所占内存长度
    return 0;
}

程序输出结果:

size of student1: 60
成员实际占用内存大小系统开辟内存空间大小
sex12
id44
name[20]2020
score44
addr[30]3030

这个时候除了成员sex之外,其余成员的自身对齐数均是2的整数倍,因此成员sex需要根据对齐数2进行内存对齐,开辟2字节空间存储,但实际只使用1字节空间,最后打印结构体变量student1的所占内存长度为60。

【C语言】——结构体进阶:结构体的内存对齐(超详细) 关于结构体,你想知道的都在这里!!! 超详细版本!!! 阅读详情

相关推荐

C语言-结构体内存对齐

结构体内存如何对齐? 为什么存在内存对齐 ? offsetof - 宏

linkang007的博客 1255

C语言——结构体(struct)对齐

本文主要介绍C语言中,结构体的对齐规则、如何改变对齐数,对齐规则对内存的影响以及如何减小结构体占用的内存。了解结构体的对齐规则对于提高内存使用效率、保证访问速度、避免硬件异常以及提高代码的可移植性都具有重要意义。在编写涉及结构体操作的代码时,我们应该了解和考虑这些对齐规则。

脑壳有点痒,好像要长脑子了! 1万+

C语言结构体对齐与函数指针:内存优化与回调机制详解

内存对齐是计算机系统中提升数据访问效率的基础技术,其原理在于CPU按特定字节边界读取内存,未对齐的数据会导致多次内存访问从而影响性能。在C语言编程中,结构体对齐通过编译器自动插入填充字节来优化内存布局,这对系统编程和嵌入式开发尤为重要。函数指针作为C语言的核心特性,实现了回调机制和多态行为,是构建灵活软件架构的关键技术。通过结构体对齐优化内存使用效率,结合函数指针实现高级编程模式,开发者能够编写出性能更高、可维护性更强的代码。本文深入解析结构体对齐原则和函数指针应用,帮助读者掌握这些底层机制在内存管理和回调

weixin_33946605的博客 470

结构体的对其规则以及为什么要对其

结构体的内存对齐规则以及为什么要对齐 内存对齐规则 1. 第一个成员在与结构体变量偏移量为0的地址处。 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 (VS中默认的值为8) 3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍 处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数 倍。 为什么存在内存对齐?

灌江口小二郎的博客 1601

嵌入式C语言结构体:内存布局、对齐与硬件映射

结构体是C语言中组织复合数据的基础机制,其本质是用户定义的内存布局蓝图,通过确定的成员偏移和对齐规则实现数据与物理内存的精确映射。理解结构体内存模型,是掌握嵌入式系统中寄存器映射、协议解析和DMA传输等底层操作的前提;它支撑着外设驱动开发、通信帧解析及RTOS任务间安全数据封装等核心实践。尤其在资源受限的MCU环境中,合理运用结构体可显著降低耦合、提升实时性,并避免因内存对齐或地址传递错误引发的HardFault。本文深入剖析结构体在嵌入式C开发中的原理、陷阱与高阶应用。

weixin_42607969的博客 410

C 语言结构体的大小:如何计算与影响因素

内存对齐是为了提高数据访问的效率,现代计算机体系结构通常要求数据类型按照某些边界进行存储。例如,4 字节类型(如int)通常要求存储在 4 字节边界上,这样可以提高 CPU 对数据的访问效率。内存对齐要求根据数据类型的大小和 CPU 架构的不同而有所不同。内存对齐规则:数据成员在结构体中的存放地址通常是它们类型大小的倍数。例如,一个int类型的成员通常存储在内存地址为 4 的倍数上。由于内存对齐,结构体的总大小有时会超过成员大小的简单总和。成员的类型和顺序:成员类型直接影响结构体的大小。例如,char比。

m0_62599305的博客 823

C语言结构体内存对齐机制详解

内存对齐是计算机体系结构中的重要概念,指数据在内存中的存储地址需要满足特定倍数关系。其原理源于现代CPU的访存特性,未对齐访问可能导致性能下降或硬件异常。在C语言中,结构体的内存布局直接受对齐规则影响,这关系到程序运行效率和跨平台兼容性。通过分析结构体成员排列、填充字节和编译器指令,可以优化内存使用和访问性能。该技术在嵌入式开发、通信协议处理等场景尤为重要,涉及硬件寄存器映射、数据解析等关键操作。本文以典型结构体案例和#pragma pack用法为例,深入解析对齐机制的实际应用。

weixin_30248619的博客 317

嵌入式C语言结构体:内存布局、对齐优化与硬件映射

结构体是C语言中组织复合数据的基础机制,其核心在于将逻辑相关的多个字段封装为原子化、内聚化的内存单元。通过编译器控制的对齐规则与填充策略,结构体在运行时呈现确定性的内存布局,这对嵌入式系统中的DMA传输、低功耗快照及Flash操作至关重要。合理利用字段重排、packed属性和联合体,可在内存受限场景下实现精准的空间优化;而结合volatile指针与寄存器偏移定义的结构体映射,则成为驱动外设、构建CMSIS等标准抽象层的关键范式。本文深入解析结构体在嵌入式开发中的工程实践,覆盖初始化安全、指针传递、数组容器及

weixin_42186387的博客 50

C语言结构体内存对齐机制详解与优化实践

内存对齐是计算机系统中重要的底层优化技术,其核心原理是要求数据在内存中的地址必须是特定值的整数倍。这种机制源于现代CPU的硬件特性,处理器通常以字长为单位进行内存访问,对齐的数据可以在单个内存周期内完成读取,从而显著提升访问速度。在C语言开发中,结构体作为复合数据类型,其成员排列直接影响内存对齐效果。通过合理优化成员顺序,可以减少填充字节,优化缓存利用率,这在嵌入式系统、高性能计算等对内存敏感的场景中尤为重要。本文基于结构体基础和内存对齐概念,深入解析对齐原则,并通过实际代码演示不同成员排列对内存占用的影响

weixin_33585822的博客 326

Visual Studio Code 打开java项目

在 Visual Studio Code 中打开并运行一个 Java 项目之前,你需要确保你已经完成了一些初始设置。

2674

Materials Studio多层聚合物建模全流程:从Build Layers到LAMMPS data文件导出避坑指南

本文详细解析了使用Materials Studio构建多层聚合物模型并导出为LAMMPS data文件的全流程。重点剖析了Build Layers工具的核心逻辑、真空层处理技巧,并提供了解决导出过程中Z轴坐标偏移问题的实战方案,特别是如何利用msi2lmp工具的-shift参数进行精准校正,确保模型在LAMMPS中模拟的稳定性和准确性。

hhh00的博客 913

C语言结构体内存对齐机制详解与性能优化实践

内存对齐是计算机体系结构中的基础概念,指数据在内存中的存储地址必须是其自身大小的整数倍。其原理源于CPU以固定大小的块(如4字节或8字节)访问内存,对齐访问可避免多次内存操作,显著提升程序性能。在C语言编程中,结构体作为重要的复合数据类型,其内存布局直接影响内存利用率和访问效率。通过理解成员对齐规则、结构体整体对齐要求以及嵌套结构体的对齐机制,开发者可以优化数据结构设计。特别是在高性能计算、嵌入式系统和网络通信等应用场景中,合理的内存对齐策略能够减少填充字节、提高缓存命中率。本文基于结构体设计和内存优化等热

weixin_31188927的博客 236

[UE5蓝图基础二]1.[1d混合空间] 走和跑的动画切换(shift切换)

再双击”run”进去 我们需要给他指定一个动画姿势,这里就需要给他我们前面做的”1d”混合空间,然后可以看到”1d” 上有个speed参数,代表的速度 从前面的逻辑来看需要通过控制速度来切换动画,那么必然不能写死速度,把速度提升为变量传递进来即可,所以就得到以下蓝图节点。混合空间的概念:混合空间就是可以将角色多个动画混合在一起 ,我们创建动画类就是创建个”Animation”文件夹 在文件夹内创建混合空间。我们目前要实现的是一个走和跑的功能 那么创建1d即可。到这一步混合空间已经做完 下一步做”动画蓝图”

qq_30584617的博客 3299

零基础入门C语言之深入结构体

本文系统讲解了C语言结构体的相关知识,主要包括三个方面:结构体类型的声明、初始化和自引用机制;结构体内存对齐规则及其原因,分析了不同情况下的内存分配方式;位段的定义、实现及其跨平台问题。文章通过示例代码详细演示了结构体的各种特性,解释了内存对齐带来的空间与时间权衡,并特别指出了位段在节省内存方面的优势及其使用注意事项。最后总结了结构体参数传递的最佳实践,建议使用指针传参以提高性能。全文内容丰富实用,适合C语言学习者深入了解结构体相关的核心概念。

su17643217590的博客 1218

无需Python环境!纯C#上位机+OpenCVSharp4+ONNX Runtime实现YOLOv8摄像头实时流检测,工业级稳定

摘要 工业自动化C#开发中,传统Python方案实现视觉检测功能存在环境依赖、内存泄漏和性能不稳定等问题。本文提出基于.NET 8+OpenCVSharp4+ONNX Runtime的纯C#方案,通过实际案例验证其优势: 零Python依赖,支持离线部署 内存稳定(380MB/72h),检测延迟<80ms 检测精度达漏检率<0.1%,误检率<0.5% 保留原有业务逻辑代码,3天完成适配 方案采用分层架构设计,支持多种硬件平台和操作系统,提供从模型导出到部署的全流程指导,为工业视觉检测提供高

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 196

微信小程序 - 详细解决web-view公众号文章或第三方网站分享转发后打开失败,页面显示“无法打开该页面,不支持打开“、“页面不存在“报错提示,苹果IOS系统手机打开是空白页,安卓手机系统会有提示!

微信小程序,公众号文章,第三方H5网页,内嵌网站分享后打不开,web-view,页面分享,小程序里公众号文章转发后无法打开,白屏,页面空白什么都没有,不支持打开,无法打开该页面,页面不存在,业务域名配置好了还是不行,公众号和小程序已经关联,iOS端苹果真机打开空白页,安卓手机,页面分享后,用户打不开提示错误,提示页面不存在,如何解决页面提示无法打开该页面,微信小程序web-view无法打开该页面不支持打开的解决方法,无法打开该页面不支持打开,最新详细解决方案,分享之后无法打开页面,提示无法打开该页面,不支持

🏆 前端领域优质创作者 1万+

C语言基础【27】:结构体类型对齐

总结:也就是说每个成员必在一个分配单位中,不能分行,并且要从头开始按自身偏移量找位置。而每行大小由最大基本类型决定。1.2确定成员偏移量:成员自身类型的整数倍,也就是实现对齐的工作,得到每个分配单位首地址为成员首地址。类型决定 b.内结构体成员偏移量为其最大基本类型。1.1确定分配单位(一次分配字节数):结构体中最大。1.3结构体总大小等同于分配单位的整数倍。c.内结构体大小为其最大基本类型的整数倍。a.分配单位由所有结构体中最大。1.4结构体嵌套结构体。

m0_65085018的博客 147

2026年医疗AI的可信革命全栈实现(上)

医疗AI可信化:贝叶斯网络与向量数据库的协同架构 本文探讨2026年医疗AI发展的关键转折点——从追求生成能力转向构建可信决策系统。核心观点认为,医疗AI下一阶段的竞争焦点在于不确定性量化和错误传播约束,而非单纯的问答流畅度。研究提出以Python为开发语言、结合向量数据库与贝叶斯网络的混合架构: 技术分层 语言层(LLM):处理自然语言交互与工具调用 证据层(Milvus/Qdrant):实现可审计的临床知识检索 概率层(pgmpy/PyMC):执行贝叶斯推理与风险路由 治理层:确保权限控制与人工复核机制

AllenLV的博客 1151

结构体的内存对齐--结构体大小

该篇文章会讲解结构体的大小计算问题,仅适用已经充分了解结构体知识的朋友。

每一行代码都会有改变世界的力量~ 354

Ubuntu搭建Pytorch环境(Anaconda、Cuda、cuDNN、Pytorch、Python、Pycharm、Jupyter)

Ubuntu搭建Pytorch环境(Anconda、Cuda、Pytorch、Python、Pycharm、Jupyter)

funfan的博客 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深入理解内存对齐:从硬件原理到C语言结构体优化实践

内存对齐是计算机系统中提升内存访问效率的核心机制,它源于硬件对数据访问的自然限制。现代处理器和内存子系统通常要求数据按照特定边界(如4字节、8字节)存放,以实现单周期高效访问。这一原理直接影响着程序性能与硬件兼容性,尤其在嵌入式系统、网络通信和硬件交互等场景中至关重要。在C语言编程中,结构体的内存布局直接受对齐规则支配,通过理解数据类型自身对齐值、结构体对齐规则及编译器填充机制,开发者可以优化数据结构以减少内存浪费并提升访问速度。合理运用#pragma pack指令或C11标准对齐控制,能在跨平台数据传输和

weixin_30571465的博客 373

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C语言结构体

结构体是 C 语言从变量走向数据模型的关键一步。本文不止讲定义和初始化,更会把数组、指针、动态内存、函数传递、嵌套自引用一路串起来,并深入到面试和工程中拉开差距的内存对齐、位字段与柔性数组。

Kkkukku的博客 478

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

格式规范与内存对齐

本文摘要: 代码规范方面,强调统一缩进(4空格或Tab)、命名规范(蛇形、帕斯卡等)、括号与空格使用规则(运算符前后加空格等)以及注释要求(单行//、多行/* */)。结构体和共用体内存管理上,结构体采用内存叠加与对齐,总大小为成员之和加填充;共用体共享内存,大小为最大成员尺寸。重点讲解了内存对齐规则:结构体成员需按自身大小对齐,整体需按最大成员对齐;共用体直接按最大成员对齐。通过示例说明了不同数据类型的对齐计算方式。

2501_93275026的博客 928

自定义类型:结构体

本文主要介绍了C语言中结构体的相关知识,包括结构体声明、内存对齐、传参和位段实现。首先回顾了结构体的基本声明和初始化方式,重点讲解了结构体变量的两种初始化方法。接着深入分析了结构体内存对齐规则及其原理,通过实例演示了如何计算结构体大小,并解释了内存对齐带来的性能优化。随后讨论了结构体传参的最佳实践,建议优先传递结构体地址而非整个结构体。最后详细讲解了位段的概念、内存分配方式、跨平台问题及使用注意事项,指出位段虽能节省空间但存在可移植性问题。全文通过代码示例和详细分析,全面阐述了结构体在C语言中的关键特性和应

mingxunwwww的博客 1915

c语言学习笔记:const指针、void指针与结构体

因为int要存在4的倍数位置,short占了0-1,int就得从4开始,占4-7,char占8,整体再对齐到4的倍数,就是12。普通指针比如char*、int*,不仅保存地址,还有明确的指向,知道一次访问多少字节。这两种写法一样,const修饰的是*p,也就是p指向的内容不能改,但p本身的指向可以改。这部分内容里,const修饰指针的三种情况和结构体对齐是最容易出错的,得多写代码验证。p的指向不能改,*p的内容也不能改,定义时必须初始化。p指针本身是只读的,不能改指向,所以定义的时候必须初始化。

2401_88406318的博客 625
上一篇: MATLAB R2022a 安装教程(超详细!附下载链接)
下一篇: 【SoC FPGA】HPS启动过程
白码王子小张
博客等级 码龄7年 6665粉丝 121原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值