C语言内存管理——内存对齐与共用体union
📅 2026/7/5 4:06:29
👁️ 阅读次数
📝 编程学习
C语言内存管理——内存对齐与共用体union
前言
在C语言中,内存管理是程序员必须掌握的核心技能。本文将深入探讨两个重要概念:内存对齐和共用体(union)。理解它们不仅能帮你写出更高效的代码,还能在面试中脱颖而出。
一、内存对齐
1.1 什么是内存对齐
不管是结构体,还是普通的变量,都存在内存对齐的现象。简单来说,内存对齐就是数据只能存放在自己类型整数倍的内存地址上。
对齐规则:数据只能放在自己类型整数倍的内存地址上。简单理解:内存地址 ÷ 占用字节 = 可以整除。
1.2 常见类型的对齐规则
| 数据类型 | 占用字节 | 对齐要求 |
|---|---|---|
| char | 1字节 | 内存地址能被1整除(任意位置) |
| short | 2字节 | 内存地址能被2整除 |
| int / float | 4字节 | 内存地址能被4整除 |
| long long / double | 8字节 | 内存地址能被8整除 |
1.3 结构体的内存对齐
结构体的内存对齐在上面的基础上又多了一条规则:
⚠️结构体总大小规则:结构体的总大小必须是其内部最大类型的整数倍(用来确定最后一个数据补位的情况)。
来看一个例子:
structExample{chara;// 1字节intb;// 4字节charc;// 1字节};// 内存布局(假设起始地址为0):// 地址0: a (char, 1字节)// 地址1-3: 补3个空字节(int需要4字节对齐)// 地址4-7: b (int, 4字节)// 地址8: c (char, 1字节)// 地址9-11: 补3个空字节(总大小需是int的整数倍,即4的倍数)// 总大小:12字节注意:对齐的时候会补空白字节,但是不会改变原本字节的大小。char补位之后,本身还是1个字节。
1.4 优化技巧
为了节约空间,我们通常会把小的数据类型写在最上面,大的数据类型写在最下面。
// 优化前:12字节structBad{chara;// 1字节intb;// 4字节charc;// 1字节};// 优化后:8字节structGood{chara;// 1字节charc;// 1字节(小的放一起)intb;// 4字节};只是调整了成员顺序,就从12字节减少到了8字节,节省了33%的空间!
二、共用体union
2.1 什么是共用体
共用体,也叫联合体、共同体,是一种特殊的数据类型。它的特点是:所有成员共享同一块内存空间。
2.2 共用体的特点
- 所有的变量都使用同一个内存空间
- 每次只能给一个变量进行赋值,因为第二次赋值时会覆盖原有的数据
- 所占的内存大小 = 最大成员的长度(也受内存对齐影响)
#include<stdio.h>unionData{inti;floatf;charc;};intmain(){unionData data;data.i=10;printf("i = %d\n",data.i);// i = 10data.f=3.14f;printf("f = %.2f\n",data.f);// f = 3.14printf("i = %d\n",data.i);// i的值被覆盖了,变成垃圾值printf("sizeof(union Data) = %zu\n",sizeof(unionData));// 4字节return0;}2.3 共用体的内存大小
- 以最大的单个成员的长度为准
- 总大小一定是最大单个成员的整数倍
- 同样受内存对齐规则的影响
三、结构体和共用体的区别
| 对比项 | 结构体 struct | 共用体 union |
|---|---|---|
| 含义 | 一种事物中包含多个属性 | 一个属性有多种类型 |
| 存储方式 | 各存各的,互不影响 | 存一起,多次存会覆盖 |
| 内存占用 | 各个变量的总和(受内存对齐影响) | 最大类型的大小(受内存对齐影响) |
| 使用场景 | 描述一个对象的多个属性 | 节省内存、类型转换、协议解析 |
四、总结
- 内存对齐:是CPU访问效率的优化机制,记住"小的放前面"的优化原则
- 共用体:所有成员共享内存,适合"同一时间只用一种类型"的场景
- 结构体 vs 共用体:结构体是"与"的关系,共用体是"或"的关系
掌握这些内存管理的细节,能让你对C语言的底层机制有更深刻的理解。
编程学习
技术分享
实战经验