您现在的位置是:首页 >技术交流 >嵌入式 C/C++ 开发之压榨程序大小——结构体优化:用好了能省 50% 的空间网站首页技术交流

嵌入式 C/C++ 开发之压榨程序大小——结构体优化:用好了能省 50% 的空间

不解之榬 2025-07-12 00:01:03
简介嵌入式 C/C++ 开发之压榨程序大小——结构体优化:用好了能省 50% 的空间

嵌入式 C/C++ 开发之压榨程序大小——结构体优化:用好了能省 50% 的空间

CC++ 编程中,结构体(struct)的内存布局对程序的性能和内存使用有着重要的影响,尤其是在嵌入式开发中,RAM 也就那么 16K8K 甚至 4K,寸土寸金,容不得一丝浪费。本文将详细介绍如何通过理解对齐要求、填充、结构体重新排序等技术来优化结构体的内存布局,缩小程序占用空间,从而提高程序的效率和性能。

1. 对齐要求

编译器在内存中布局基本数据类型时受到对齐要求的约束,以加快内存访问速度。这些约束导致了相同的布局,包括 IntelARMRISC-V 等架构。除了 char 类型外,其他基本的 C 语言数据类型都有对齐要求。例如,2 字节的 short 必须从偶数地址开始,4 字节的 intfloat 必须从能被 4 整除的地址开始,8 字节的 longdouble 必须从能被 8 整除的地址开始。这种自我对齐的特性使得内存访问更快。
但是,这也导致了部分内存空间的额外占用——填充。

2. 填充

填充是指编译器在结构体成员之间或结构体末尾添加的额外字节,以满足对齐要求。例如,考虑以下结构体(64 位系统下):

struct foo1 {
    char *p;     /* 8 字节 */
    char c;      /* 1 字节 */
    long x;      /* 8 字节 */
};

在这个结构体中,char 类型的 c 成员后面需要添加 7 字节的填充,以确保 long 类型的 x 成员从 8 字节对齐的地址开始:

struct foo1 {
    char *p;       /* 8 字节 */
    char c;        /* 1 字节 */
    //char pad[7]; /* 7 字节填充 */
    long x;        /* 8 字节 */
};

这种填充虽然可以确保数据的快速访问,但也导致内存的浪费。

3. 结构体对齐和填充

结构体的对齐通常是按照其成员最宽的长度进行对齐。例如,如果一个结构体包含一个 long 类型的成员,那么整个结构体将具有 8 字节对齐。这意味着结构体的地址与其第一个成员的地址相同,没有前面的填充。然而,结构体的末尾可能会有尾随填充,以确保下一个结构体实例从正确的对齐地址开始。

4. 位字段

位字段允许你在结构体中声明小于字符宽度的字段,小到 1 位。例如:

struct foobits {
    short s;
    char c;
    int flip:1;
    int nybble:4;
    int septet:7;
};

位字段的布局受到 C 标准的限制,它们不能跨越存储单位边界。C99 保证位字段将尽可能紧密地打包,但 C++14 放宽了这一限制,允许位字段跨越多个分配单元。

5. 结构体重新排序

由上述对其及填充的规则学习得知,我们可以通过重新排序结构体成员,来减少填充并优化内存布局。
通常,按对齐要求从大到小的顺序排列成员可以减少填充。
例如,将指针对齐的成员放在前面,然后是 4 字节的 int,接着是 2 字节的 short,最后是 char 类型的成员。
这种方法可以显著减少结构体的总体大小,从而提高内存使用效率。

6. 结构体优化的实际应用

考虑一个复杂的结构体,包含多种不同类型的数据成员:

struct complex {
    char c1;
    int i1;
    short s1;
    long l1;
    char c2;
};

在这个结构体中,c1c2 之间以及 l1 末尾会有填充。通过重新排序成员,我们可以减少填充:

struct complex {
    long l1;
    int i1;
    short s1;
    char c1;
    char c2;
};

这种重新排序后的结构体只在 l1i1 之间有 4 字节的填充,因为 i1 需要 4 字节对齐。c1c2 之间没有填充,因为 c1 已经在 i1 的填充内。

优化对比,文末可获取 demo
image.png

结论

理解并应用结构体优化技术对于提高 CC++ 程序的性能和内存效率至关重要。
通过对齐要求、填充和结构体重新排序的理解,开发者可以设计出更高效、更紧凑的数据结构,从而在保持代码可读性的同时,提高程序的整体性能。
记住,优化结构体不仅仅是减少内存占用,它还可以提高程序的运行速度,特别是在处理大量数据或在内存受限的环境中。

文章配套 demo 源码仓库:结构体优化对比demo

也可扫码关注博主同名公众号"不解之榬",私信获取
不解之榬

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。