对《C语言:内存字节对齐详解——struct 和 union 》的理解

C语言 union 与 struct 内存布局对比:3个实例解析字节对齐与空间差异 本文深入对比了C语言中union与struct的内存布局差异,通过3个实例解析字节对齐规则与空间优化策略。详细分析了共用体(union)和结构体(struct)在嵌入式开发中的实际应用,帮助开发者理解数据存储原理并提升程序性能。重点关注内存对齐、嵌套结构和位域等高级技巧,为系统级编程提供实用指导。 阅读详情

本文是对先前转载的一篇C语言:内存字节对齐详解http://blog.youkuaiyun.com/crystaldestiny/article/details/12953199的学习和理解,主要以一个例子来分析,首先还是重新提一下理解这个例子的必备知识:


对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,其自身对齐值为4,double类型,其自身对齐值为8,单位字节。
这里面有四个概念值:
1)数据类型自身的对齐值:就是上面交代的基本数据类型的自身对齐值。

2)指定对齐值:#pragma pack (value)时的指定对齐值value。

3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。

4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。

       有了这些值,我们就可以很方便的来讨论具体数据结构的成员和其自身的对齐方式。有效对齐值N是最终用来决定数据存放地址方式的值,最重要。有效对齐N,就是表示“对齐在N上”,也就是说该数据的"存放起始地址%N=0".而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是 数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整 数倍,结合下面例子理解)。


下面以我自己写的一个例子程序来具体分析(基于Win 7 32位系统):

#include <stdio.h>
struct A{
    char a;
    short b;
double c;
int d;
};
struct B{
char e;
A a;
};
void main()
{
printf("%d   %d",sizeof(A),sizeof(B));
}


运行结果为:24  32

sizeof(A)的结果分析:根据上面所说的,可以简单假设struct A{ }的第一个成员 char a的存储首地址为0x0000,对于char型数据,其自身对齐值为1,并且char型数据分配1个字节的内存;接着是short,其自身对齐值为2,也就是说该数据的"存放起始地址%2=0,所以该数据存储在0x0002~0x003(short型数据分配内存2个字节);然后是double c,double型自身对齐值为8,所以该数据存储在0x0008~0x000f(该数据的"存放起始地址%8=0);接着是int d,int型自身对齐值为4,所以可以连续存储在0x0010~0x0013(该数据的"存放起始地址%8=0);最后结构体自身为了保持圆整,会以成员中"有效对齐N"最大的8进行对齐,可以将这段内存看成是连续的(在这里会延伸到0x0017),中间空的地方用0填充,及考虑内存地址对齐之后struct A的占用的内存单元是0x00~0x17共24个字节;

接着分析struct B,同样假设,将char e存放在0x00,由对sizeof(A)的结果分析可以知道,struct A 以8字节对齐,(还是假设以一段连续的内存单元来存储)所以,A a的存储首地址为0x08~0x1f(注意A a 实际占用24个字节),然后用0填充,所以共32个字节。

注意:如果结构体中有数组,只需将数组看成若干个相同的单个同类型的数据,例如,将char a 改成char a [5],怎可当成是连续定义了5个char型数据。


说完了struct ,接下来再说一下 union,首先摘几句The C Programming Language里面讲述这个问题的原话:
①联合就是一个结构

②它的所有成员相对于基地址的偏移量都为0

③此结构空间要大到足够容纳最“宽”的成员

④并且,其对齐方式要适合于联合中所有类型的成员。


附图说明:


该结构要放得下int i[5]必须要至少占4×5=20个字节。如果没有double的话20个字节够用了,此时按4字节对齐。但是加入了double就必须考虑double的对齐方式,double是按照8字节对齐的,所以必须添加4个字节使其满足8×3=24,也就是必须也是8的倍数,这样一来就出来了24这个数字。综上所述,最终联合体的最小的size也要是所包含的所有类型的基本长度的最小公倍数才行。(这里的字节数均指win 32位下的值,平台、编译器不同值也有可能不同。)


【纯血鸿蒙】安装hdc工具 参考资料: 阅读详情

相关推荐

Android 白名单保活实战:主流厂商适配指南

本文详细解析了Android应用白名单保活的实战策略,重点针对华为、小米、OPPO、vivo等主流厂商的系统特性,提供了精准的后台设置页面跳转适配方案。文章从基础的前台服务实现讲起,深入讲解了白名单的判断、申请与厂商适配的核心代码与避坑指南,旨在帮助开发者合规、稳定地提升应用后台存活率。

motor的博客 1861

关于字节对齐问题

我们的讨论从一道经典的题目开始: Intel和微软同时出现的面试题 #pragma pack(8) struct s1{ char a; long b; }; struct s2{ char c; s1 d; long long e; }; #pragma

与狼共舞 的专栏 2142

CentOS7下Ollama部署全攻略:从安装到自定义端口配置(附国内加速技巧)

本文详细介绍了在CentOS7系统上部署Ollama的完整流程,包括环境准备、模型下载优化、服务化部署及端口配置等关键步骤。特别针对国内网络环境提供了加速安装方案和镜像源配置技巧,帮助开发者快速搭建稳定的本地AI运行环境。

mmm90的博客 289

字节对齐规则

字节对齐这块知识点看了好几遍,总是忘,今天又碰到了,就在这整理一下。 64位与32位编译器操作系统的区别: 1 、64位与32位linux c开发时默认字节对齐方式分别为8和4字节。 2 、 32和64位C语言内置数据类型,如下表所示: 上表中第一行的大写字母和数字含义如下所示: I表示:int类型 L表示:long类型 P表示:pointer指针类型 32表示

shengabc的专栏 3912

opencv简单小项目

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,它提供了大量的图像和视频处理功能。要开始一个OpenCV项目,你需要安装OpenCV库,这通常可以通过Python的pip包管理器完成。替换为你要加载的图像的实际路径。这个例子展示了OpenCV项目的基本结构,你可以在此基础上添加更多的图像处理功能。如果你需要更详细的指导或代码示例,请告诉我你的具体需求。

youyouxiong的博客 972

RK3588网络调试笔记:当我把默认RTL8211F PHY换成另一款时,踩了哪些坑?

本文详细记录了在RK3588平台上将默认RTL8211F PHY芯片替换为其他型号的全过程,包括硬件设计验证、内核驱动适配、复位时序配置等关键步骤。通过实际案例分享,提供了从驱动调试到硬件优化的系统性解决方案,帮助开发者高效完成PHY芯片替换,确保网络接口稳定性。

weixin_30291791的博客 669

C struct 字节对齐

c struct 字节对齐

dumcce2017的博客 595

达梦DCA2023年10月培训及考试总结

本次培训共分三天,培训内容不单单是DCA的单机安装、实例创建、库表操作等,培训内容是把关系型数据库的理论及DM8的产品结合起来讲,很实用。具体的考试则是需要个人大量的线下练习,考试总体而言都是培训讲过的内容,只要用心听,好好练习,哪怕是没有计算机基础的童鞋也能考过。提示:以下是本篇文章正文内容,下面案例可供参考总体而言,本次考试不是很难,用心准备,考前认真听讲,考后多次练习,基本都能通过。

qinjuao的博客 2321

c语言联合体中字节对齐,C语言编程中的联合体union入门学习教程

联合体(union)在C语言中是一个特殊的数据类型,能够存储不同类型的数据在同一个内存位置。可以定义一个联合体使用许多成员,但只有一个部件可以包含在任何时候给定的值。联合体会提供使用相同的存储器位置供多用途的有效方式。定义联合体要定义联合体,必须使用union语句很相似于定义结构。联合体声明中定义了一个新的数据类型,程序不止一个成员。联合体声明的格式如下:union [union tag]{mem...

weixin_35524152的博客 867

用 MATLAB 实现鼻子和嘴的检测

为了方便起见,这里我们使用了 CascadeObjectDetector 中自带的 haarcascade_frontalface_alt2.xml 文件,该文件包含了多个包含鼻子和嘴的样本图像。其中 bbox 变量表示检测到的所有鼻子和嘴的边界框信息。在图像处理中,鼻子和嘴的检测是十分重要的一项任务。本文将介绍如何使用 MATLAB 实现鼻子和嘴的检测,并提供相应的源代码。然后,我们可以调用之前创建的 detector 对象来进行鼻子和嘴的检测。综上所述,我们可以使用以上代码实现鼻子和嘴的检测。

qq_39605374的博客 256

【Windows Server 2019】存储服务器的配置和管理——iSCSI的安装和配置(下)

博文介绍了如何使用Windows 10 和 ESXi 验证iSCSI服务器部署成功以及如何管理iSCSI服务 。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 8001

C struct 中字节对齐问题

VC中下面几个结构体大小分别是多少呢struct MyStruct {     double m4;     char m1;     int  m3; }; struct MyStruct {     char m1;     double m4;     int m3; }; #pragma pack(push)//保存对齐状态 #p

ehui928的专栏 8921

【DEIM创新改进】全网独家创新、注意力改进篇 | AAAI 2026 | DEIM 引入轻量级群体注意力(LWGA)模块,可以显著提高其多尺度物体检测能力,特别是在小物体和复杂背景下的表现

本文提出了一种改进的DEIM网络模型,通过引入轻量级LWGA模块显著提升了多尺度物体检测性能。LWGA模块采用局部和全局注意力机制,有效提升了小物体和复杂背景下的识别能力,同时保持低计算成本。该模块通过分割输入特征图并应用多种注意力机制(GPA、RLA、SMA、SGA)进行特征提取和融合,优化了多尺度物体的特征表示。实验表明,改进后的DEIM模型在遥感图像处理等任务中表现出色,在12个数据集上实现了性能与计算效率的最佳平衡,为资源受限设备提供了高效的解决方案。

Ai缝合怪、助力小伙伴高效发论文 273

[C语言]struct和union的区别 大小端 字节对齐详解

C语言struct和union的区别,大小端,字节对齐详解

yjlyyj的博客 1696

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

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

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

C 语言核心关键字与数据结构:volatile、struct、union 详解

本文解析 C 语言volatile、struct、union的用法与核心差异。volatile禁止编译器缓存变量,确保从内存取最新值,适用于中断、多线程等场景;struct封装不同类型数据,需掌握字节对齐及 C/C++ 区别;union成员共享内存,可节省空间、判断 CPU 大小端。三者是嵌入式与系统编程基础,理解原理能规避开发陷阱。

weixin_73308349的博客 1071

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

详解下c语言中struct和union的对齐规则

接触过c语言的同学应该都知道字节对齐。有些时候我们很容易弄错字节对齐的方式,特别是涉及到struct(结构体)和union(联合体)时。今天我们通过详细例子来说明下struct和union的对齐规则,以便了解各种struct和union所占字节具体计算方式。

tpc4289的专栏 929

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C语言标识符之define,typedef,union,struct和位域的综合理解

typedef,union,struct及位域等标识符和知识点

weixin_49297378的博客 1401

结构体(struct)和联合体(union)的区别

U5中a四个字节,后面b和c加起来3个字节,正好补1个字节对齐;U6中b1个字节,要和后面的a对齐,需要补3个字节对齐,c也要补1个字节对齐,因而最终U6为12个字节。另外,要想改变这种默认对齐设置,可以用。代码中U3至少容纳最大e[5]=20字节,同时变量类型最大值是整数倍,即使double(字节数是8)的整数倍,因而sizeof(U3)=24。所有成员共用一块存储空间,在操作不同的成员时,编译器根据不同的成员类型,按照不同的方式取值。#pragma pack () /*取消指定对齐,恢复缺省对齐*/

快乐的小鱼123 5万+

C语言中,struct与union的区别

struct和union是C语言中两种不同的数据结构,两者都是常见的复合结构,其区别主要表现在两方面: 1、联合体中所有成员共用一块地址空间,即联合体只存放了一个被选中的成员,而结构体中所有成员占用空间是累加的,其所有成员都存在,不同成员会存放在不同地址。 在计算一个结构体变量的总长度时,其内存空间大小等于所有成员长度之和(需考虑字节对齐);而在联合体中,所有成员不能同时占用内存空间,它们不能

zhaojian_li的专栏 5608

关于struct和union存储的内存字节对齐的问题

这是在读winnt.h头文件的源代码时发现了一段自己弄不明白的代码,继而牵扯到了结构体存储的内存边界对齐的问题。该问题在MSDN中说的比较少。以下是阅读MSDN中的一些重要信息:1.可以使用 #pragma pack 指令来指定对齐字节,该指令指定内存对齐字节的功能和编译器选项 /Zp 是等效的。2.#pragma指令对该指令之后的 struct 或 union 的声明有效。如果把这条指令

jcwKyl的专栏 4342

union和struct的一些区别小结

union和struct的一些区别小结 1. union union中的所有成员共同占用一段内存,union的长度可以用sizeof运算符来求,union的长度要求必须: 1.至少要容纳最大成员类型变量的大小 2.必须是所有成员变量类型大小的整数倍 typedef union MyUnion//变量共同占用一段内存 { long i; int x; char a[17]; }TestUnion; int main() { TestUnion date; cout<<sizeof(da

qq_40877617的博客 319

struct和union的区别

今天读到NeHe第48章的源程序,本想学习一下轨迹球的用法,无意中发现里面用到 union 。当初学习C语言时并没有特别注意 union 的用法,也不知道与 struc t相比有何不同。经过网上的一番搜索,现在总算是恍然大悟,所以就小结一下。如有错误之处,敬请指正。( struct 和 union 的结构定义形式没有多大差别,只要不是初学者,相信大家不会在这方面存在什么问题。)  

无为 1461

struct与union的对齐方式解析

一、Struct 和 Union有下列区别: 1.在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct 可以存储多个成员信息,而union每个成员会用同一个存储空间,只能存储最后一个成员的信息 2.都是由多个不同的数据类型成员组成,但在任何同一时刻,union只存放了一个被先选中的成员,而结构体的所有成员都存在 3.对于union的不同成员赋值,将会

bv1315008634的博客 1291

C++:struct和union 内存字节对齐问题

struct内存对齐问题1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有stru

BAOLIANG196的博客 3850

struct和union内存计算

常见内存计算基本变量类型内存struct内存计算方式union内存计算方式 基本变量类型内存 一般情况下: bool 1字节 char 1字节 int 4字节 float 4字节 short 2字节 double 8字节 long 8字节 const char* str = "hello"; char str2[] = "he"; cout << sizeof(str) << endl; //指针占4字节 cout << sizeof(str2) << en

BigBoss_Yatou的博客 993

关于Union和Struct对齐

关于union,struct,还有机器数赋值,总是感觉自己认识不是特别深刻,这里使用小DEMO程序加以说明,具体的详细细节描述其它地方已经有说明和记录,这里不再说明。 #include union myun { struct { int x; int y; int z; }u; int k; }a; int main() { a.u.x =4; a.u.y =5;

IT-Goer 640
上一篇: C语言:内存字节对齐详解
下一篇: java学习之编译时类型(前期绑定)和运行时类型 (后期绑定、动态绑定、运行时绑定)
@Agony
博客等级 码龄14年 16粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值