C语言内存管理——内存对齐与共用体union

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 结构体的内存对齐

结构体的内存对齐在上面的基础上又多了一条规则:

⚠️ 结构体总大小规则: 结构体的总大小必须是其内部最大类型的整数倍(用来确定最后一个数据补位的情况)。

来看一个例子:

c 复制代码
struct Example {
    char a;     // 1字节
    int b;      // 4字节
    char c;     // 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 优化技巧

为了节约空间,我们通常会把小的数据类型写在最上面,大的数据类型写在最下面。

c 复制代码
// 优化前:12字节
struct Bad {
    char a;     // 1字节
    int b;      // 4字节
    char c;     // 1字节
};

// 优化后:8字节
struct Good {
    char a;     // 1字节
    char c;     // 1字节(小的放一起)
    int b;      // 4字节
};

只是调整了成员顺序,就从12字节减少到了8字节,节省了33%的空间!


二、共用体union

2.1 什么是共用体

共用体,也叫联合体、共同体,是一种特殊的数据类型。它的特点是:所有成员共享同一块内存空间

2.2 共用体的特点

  1. 所有的变量都使用同一个内存空间
  2. 每次只能给一个变量进行赋值,因为第二次赋值时会覆盖原有的数据
  3. 所占的内存大小 = 最大成员的长度(也受内存对齐影响)
c 复制代码
#include <stdio.h>

union Data {
    int i;
    float f;
    char c;
};

int main() {
    union Data data;

    data.i = 10;
    printf("i = %d\n", data.i);  // i = 10

    data.f = 3.14f;
    printf("f = %.2f\n", data.f); // f = 3.14
    printf("i = %d\n", data.i);   // i的值被覆盖了,变成垃圾值

    printf("sizeof(union Data) = %zu\n", sizeof(union Data)); // 4字节
    return 0;
}

2.3 共用体的内存大小

  • 以最大的单个成员的长度为准
  • 总大小一定是最大单个成员的整数倍
  • 同样受内存对齐规则的影响

三、结构体和共用体的区别

对比项 结构体 struct 共用体 union
含义 一种事物中包含多个属性 一个属性有多种类型
存储方式 各存各的,互不影响 存一起,多次存会覆盖
内存占用 各个变量的总和(受内存对齐影响) 最大类型的大小(受内存对齐影响)
使用场景 描述一个对象的多个属性 节省内存、类型转换、协议解析

四、总结

  • 内存对齐:是CPU访问效率的优化机制,记住"小的放前面"的优化原则
  • 共用体:所有成员共享内存,适合"同一时间只用一种类型"的场景
  • 结构体 vs 共用体:结构体是"与"的关系,共用体是"或"的关系

掌握这些内存管理的细节,能让你对C语言的底层机制有更深刻的理解。

相关推荐
fanstuck36 分钟前
1M 上下文能怎么用?我用 Seed Evolving 做了一个招标文件版本差异审查器
服务器·人工智能·数据分析·开源·aigc
FoldWinCard4 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
2601_954526755 小时前
【工业传感与算法实战】温漂补偿与零点抗漂破局:基于二阶多项式拟合的 C/C++ 边缘校准算法,深度拆解“压力变送器什么牌子好”的技术硬指标
c语言·c++·算法
qq_448011165 小时前
C语言中的变量和函数的定义与声明
android·c语言·开发语言
kirs_ur5 小时前
SSD 在 AI 训练中的角色
大数据·服务器·人工智能
零涂毕业设计5 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1235 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质6 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
kirs_ur6 小时前
CXL(Compute Express Link)— 内存扩展的未来
服务器·数据库·性能优化
SakitamaX6 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs