news 2026/8/5 15:51:29

C/C++结构体内存的问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C/C++结构体内存的问题

1.结构体内存布局的基本规则

1.1.成员顺序

结构体的成员在内存中按照声明的顺序依次存放。第一个成员的地址与结构体的地址相同。

struct Example { char a; // 1字节 int b; // 4字节 double c; // 8字节 short d; // 2字节 };

1.2 对齐要求和结构体大小的计算

结构体的大小不是简单地将所有成员的大小相加,而是要考虑对齐和填充。每个基本类型(如int、double、指针等)都有对齐要求。对齐要求通常是该类型的大小(以字节为单位)或者是编译器特定的值。例如,在大多数系统上,int的对齐要求是4字节,double的对齐要求是8字节。

内存对齐:

内存对齐是通过在数据间填充少量字节,使数据的起始地址满足 CPU 字长(32 位为 4 字节、64 位为 8 字节)或数据自身大小的整数倍的内存布局规则,其核心意义在于:以牺牲少量内存形成内部碎片为代价,既大幅提升 CPU 按访问单元批量读取内存的效率(避免非对齐时多次读取、拼接数据的额外开销),又能兼容不支持非对齐访问的硬件(如早期 ARM 处理器)以防止程序崩溃,同时还能避免数据跨 CPU 访问单元存储引发的截断、乱码等问题,保障数据存储的完整性与稳定性。

默认对齐规则

(无 #pragma pack,编译器默认行为)

数据类型分类对齐值计算规则64 位系统示例(对齐值 / 大小)32 位系统示例(对齐值 / 大小)
基本数据类型对齐值 = 该类型的「字节大小」(大小就是 sizeof 的结果)char:1/1short:2/2int:4/4double:8/8同 64 位(基本类型大小不变)
指针类型对齐值 = CPU 字长(64 位 = 8,32 位 = 4),与指向的类型无关int*:8/8char*:8/8double*:8/8int*:4/4char*:4/4
数组类型对齐值 = 「数组元素的对齐值」(数组整体大小不影响对齐值,只影响占用空间)char arr[5]:1/5int arr[3]:4/12double arr[2]:8/16同 64 位(元素对齐值不变)
结构体(struct)对齐值 = 其「所有成员对齐值的最大值」(和成员大小无关,只看成员的对齐值)

示例:

struct S {char c; double d;}对齐值 = max (1,8)=8

同 64 位(成员对齐值不变)
联合体(union)对齐值 = 其「所有成员对齐值的最大值」(和成员大小无关,只看成员的对齐值)

示例:

union U {int a; char b[5];}对齐值 = max (4,1)=4

同 64 位(成员对齐值不变)
嵌套结构体对齐值 = 该嵌套结构体「自身的对齐值」(而非嵌套结构体的大小)

示例:

struct Sub {char a; double b;}

// Sub对齐值 8

struct S {char c; Sub s;}

// S 的对齐值 = max (1,8)=8

同 64 位
计算规则:

规则1:如果你有一个成员_e(大小为x字节对齐值假设也为x字节)需要加入到相对结构体起始地址0偏移y byte的位置那么需要校验y是否为对齐值x的整数倍,若不为整数倍则需加最少的n字节,使得(y+n)%x = 0;
规则2:结构体总大小必须是最大对齐值的整数倍, 而非成员大小的最大值.
规则3:若类有虚函数或者虚继承,则编译器会隐式地加一个虚函数指针的大小在开头;若继承多个不同类型的父类,则会继承到多个虚函数表指针. 这些虚表指针需要计入类的大小。

基本示例:
struct Example1 { char a; // 1字节 int b; // 4字节 double c; // 8字节 }; // 由于内存对齐,可能是16字节 struct Example2 { char a; // 偏移0 double b; // 偏移8(不能放在1) char c; // 偏移16 }; // 总大小24字节(不是17,因为24是8的倍数) // 内存布局: // [a][填充7字节][b(8字节)][c][填充7字节] class MyClass { private: int a; // 4字节 double b; // 8字节 static int c; // 不计入对象大小 public: void func() {} // 函数不计入对象大小 };

2.一些案例

关于嵌套结构体:

struct Inner { int x; // 4字节 char y; // 1字节 // 填充3字节 }; // 大小: 8字节 struct Outer { short a; // 2字节 // 填充2字节 Inner inner; // 8字节 (从4字节边界开始) char b; // 1字节 // 填充7字节 }; // 大小: 24字节

3.一个特殊用法!!!

对于任何一个结构体,可以获取到任何一个元素相较于结构体起点的偏移量:

&((struct A*)0->_element)

结构体指针指向的就是结构体的起点, 同时此起点有和起始元素的地址相同;

只要我们拥有结构体某一个元素的指针,那么就可以用这个指针加上偏移量得到整个结构体的指针

可以用预处理指令定义一个宏offsetof:

#define offsetof(TYPE, MEMBER)((size_t)&((TYPE *)0)->MEMBER)

4.大小端问题

结构体本身并不决定字节序(大端或小端)也不参与字节序, 字节序是由底层的硬件架构决定的。结构体的内存布局中, 成员按照声明顺序排列(考虑对齐), 但每个成员内部的字节顺序则取决于系统的字节序

大端存储(Big-endian):高位字节存储在低地址, 低位字节存储在高地址
小端存储(Little-endian):低位字节存储在低地址, 高位字节存储在高地址

/* 结构体内部遵循硬件平台的字节序 x86/x64架构:小端序 ARM(可配置):通常小端序 PowerPC、SPARC:大端序 网络字节序:大端序 */
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/5 15:49:59

DDS技术解析:从数字合成原理到工程实践应用

1. 从模拟到数字的桥梁:DDS究竟是什么? 如果你在信号发生器、通信系统或者音频设备里翻找过技术手册,大概率会碰到一个缩写:DDS。全称是Direct Digital Synthesis,直接数字合成。这个名字听起来有点学术,但…

作者头像 李华
网站建设 2026/8/5 15:49:06

5分钟终极指南:用GModPatchTool彻底修复Garry‘s Mod启动问题

5分钟终极指南:用GModPatchTool彻底修复Garrys Mod启动问题 【免费下载链接】GModPatchTool 🇬🩹🛠 Patches for Garrys Mod. Updates/Improves CEF and Fixes common launch/performance issues (esp. on Linux/Proton/macOS). F…

作者头像 李华
网站建设 2026/8/5 15:47:05

一文讲透AI Agent:从底层原理到生产落地完整梳理

文章目录1 先唠点实在的:你天天用的Agent,到底是个啥1.1 一句话戳透本质1.2 一个万能公式记牢2 Agent干活的真面目:一边想一边干,循环往复2.1 啥是ReAct循环2.2 轨迹:Agent的打工流水账2.3 上下文累积才是精髓2.4 拆一…

作者头像 李华
网站建设 2026/8/5 15:47:05

AI浪潮下开发者如何转型:从工程能力到RAG实战的职业进阶指南

最近和不少同行交流,大家普遍感觉这两年科技圈的氛围有点“冰火两重天”。一边是时不时听到大厂优化、团队调整的消息,另一边则是AI相关的新闻和融资一轮热过一轮。这种看似矛盾的现象背后,其实反映了全球科技行业正在经历一场深刻的结构性调…

作者头像 李华
网站建设 2026/8/5 15:46:55

Lunalytics数据库迁移教程:从SQLite到PostgreSQL无缝切换

Lunalytics数据库迁移教程:从SQLite到PostgreSQL无缝切换 【免费下载链接】Lunalytics 🚀 Open source monitoring tool built with Node.js 项目地址: https://gitcode.com/gh_mirrors/lu/Lunalytics Lunalytics是一款开源监控工具,使…

作者头像 李华
网站建设 2026/8/5 15:46:27

如何正确配置XIAOMUSIC_HOSTNAME避免播放链接重复端口问题

如何正确配置XIAOMUSIC_HOSTNAME避免播放链接重复端口问题 【免费下载链接】xiaomusic 使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。 项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic XIAOMUSIC_HOSTNAME是xiaomusic音乐播放器项目中的核心配…

作者头像 李华