如何理解原始类型在内存对齐(Memory Alignment)中的字节占用逻辑

胖丽吖_1829

胖丽吖_1829

2026-05-09

314人浏览

原创

原始类型内存对齐核心是起始地址约束而非单纯字节大小:char对齐1、short对齐2、int/float对齐4、double/long long对齐8;成员偏移须满足自身对齐要求,结构体总大小须为最大对齐值的整数倍,顺序不同会导致填充差异,影响实际内存占用与访问性能。

如何理解原始类型在内存对齐(memory alignment)中的字节占用逻辑

原始类型在内存对齐中的字节占用逻辑,核心不是“它占多少字节”,而是“它要求从哪个地址开始放”。这个起始地址的约束,直接决定了结构体内存布局、填充字节的有无,以及最终的总大小。

每个原始类型自带一个对齐要求

对齐要求(也称自然对齐值)通常等于其自身大小,但并非绝对——它由硬件架构和编译器共同决定。常见情况如下:

  • char:大小1字节,对齐要求为1 → 可放在任意地址(0x00、0x01、0x02…都合法)
  • short:大小2字节,对齐要求为2 → 起始地址必须是偶数(0x00、0x02、0x04…)
  • int / float:通常4字节,对齐要求为4 → 地址必须是4的倍数(0x00、0x04、0x08…)
  • double / long long:通常8字节,对齐要求为8 → 地址必须是8的倍数(0x00、0x08、0x10…)

注意:这不是语言标准强制规定,而是主流平台(x86/x64/ARM)的默认行为。例如在某些嵌入式环境或使用 #pragma pack(1) 时,int 也可能被允许放在奇数地址上,但会牺牲性能甚至触发异常。

对齐逻辑体现在两个层面:成员偏移 + 结构体总大小

结构体不是简单累加各成员大小,而是按规则逐步安排每个成员的位置,并在末尾补足:

  • 成员偏移规则:第N个成员的起始地址,必须是它自身对齐要求的整数倍;若前一个成员结束位置不满足,就在中间插入填充字节
  • 结构体总大小规则:整个结构体所占字节数,必须是其所有成员中最大对齐要求的整数倍;若不满足,就在末尾补填充

例如:struct { char a; int b; } – a 从偏移0开始,占1字节,结束于偏移1 – b 要求4字节对齐,下一个可用的4的倍数地址是偏移4 → 编译器在偏移1–3插入3字节填充 – b 占偏移4–7 – 最大对齐要求是4,当前总长度为8 → 已是4的倍数,无需尾部填充 → 实际大小为8字节(而非1+4=5)

对齐影响真实内存布局,而不仅是理论大小

同一个结构体,成员顺序不同,内存占用可能完全不同:

Mapify
Mapify

Mapify是一款把文档、网页、视频和音频转换为思维导图的 AI 总结工具。

下载
  • struct { char a; int b; short c; } → 占12字节(a后填3字节,c后填2字节)
  • struct { int b; short c; char a; } → 占8字节(b占0–3,c占4–5,a占6,末尾补1字节对齐到8)

这种差异不是编译器“多事”,而是CPU访问效率的硬性需求:未对齐的 int 访问,在多数x86处理器上虽能运行但慢一倍,在部分ARM模式下会直接报错(SIGBUS)。所以对齐是用少量空间换确定性性能与稳定性。

特殊场景下可显式干预对齐行为

当需要精确控制内存布局(如网络协议打包、硬件寄存器映射),可通过编译器扩展临时取消默认对齐:

  • GCC/Clang:__attribute__((packed)) 强制紧凑排列,禁用填充
  • MSVC / 跨平台:#pragma pack(1) 设定1字节对齐边界

但需注意:这样做会让CPU访问该结构体成员时失去对齐保障,可能引发性能下降或运行时错误,仅应在明确知情且必要时使用。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.31

3311

5

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

2025.10.31

554

9

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

2026.02.12

562

19

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

7079

3

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

2023.11.13

2150

6

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.30

163

8

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1698

6

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

2023.07.31

12165

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程