0

0

C++ 内存对齐(Memory Alignment)是什么?(如何优化结构体的大小)

穿越時空

穿越時空

发布时间:2026-02-12 12:35:18

|

974人浏览过

|

来源于php中文网

原创

结构体大小不等于成员大小之和,因编译器插入填充字节以满足对齐要求;对齐值取成员最大对齐值,结构体总大小需为其整数倍;可通过调整成员顺序或alignas/#pragma pack手动控制。

c++ 内存对齐(memory alignment)是什么?(如何优化结构体的大小)

结构体大小为什么不是成员大小之和?

因为编译器会在成员之间插入填充字节(padding),确保每个成员的起始地址满足其对齐要求。比如 int 通常要求 4 字节对齐,如果前一个成员结束在地址 3,编译器就插 1 字节空隙,让 int 从地址 4 开始。

常见错误现象:sizeof(MyStruct) 比预期大很多,尤其在嵌入式或网络协议打包时导致内存浪费或序列化失败。

  • 对齐值取自成员中「最大对齐要求」,但受 #pragma packalignas 影响
  • 结构体自身对齐要求 = 所有成员对齐要求的最大值(向上取整到 2 的幂)
  • 末尾可能补填充,使整个结构体大小是其自身对齐值的整数倍

怎么手动控制结构体对齐?

两种主流方式:改排列顺序 + 显式对齐约束。前者零成本、最推荐;后者灵活但需谨慎。

使用场景:频繁创建大量实例(如粒子系统、点云数据)、跨平台二进制兼容、DMA 直接访问。

立即学习C++免费学习笔记(深入)”;

  • 把大对齐成员(doublelong long、指针)放前面,小的(charbool)塞中间或结尾
  • alignas(1) 强制取消对齐(慎用!可能触发未对齐访问异常)
  • #pragma pack(1) 全局禁用填充(影响后续所有结构体,建议用 push/pop 包裹)

示例:

CodeWP
CodeWP

针对 WordPress 训练的AI代码生成器

下载
struct Bad { char a; double b; char c; }; // sizeof = 24(x86_64)
struct Good { double b; char a; char c; }; // sizeof = 16

如何查某个类型的对齐要求?

别猜,用标准工具查。C++11 起有 alignof 运算符,它返回的是对齐值(不是偏移),类型本身和变量都可查。

容易踩的坑:误把 alignof(T) 当作 sizeof(T);或者在模板里忘记 alignof 是编译期常量,不能用于运行时分支判断。

  • alignof(int) 通常是 4,但取决于平台和 ABI(ARM64 上可能是 4 或 8)
  • alignof(std::max_align_t) 是当前平台支持的最大对齐值(常见为 16)
  • 结构体的 alignof 不等于成员 alignof 之和,而是最大值

什么时候不该优化对齐?

当性能瓶颈不在内存占用,而在缓存行冲突或访问延迟时,盲目压缩反而坏事。比如把原本跨缓存行的两个 int 挤进同一行,可能引发 false sharing。

典型信号:perf 显示高 L1-dcache-load-missescpu_cycles 没降反升;多线程下修改相邻字段出现性能抖动。

  • 高频访问的小结构体(
  • 含虚函数或继承的类,vptr 会固定占 8/16 字节,且影响整体对齐
  • std::vector<T> 时,T 对齐会影响分配器行为(尤其是 aligned_alloc

对齐不是越小越好,关键是匹配硬件访问模式和使用上下文。一个被 memcpy 频繁拷贝的结构体,和一个只在栈上临时构造的结构体,优化策略完全不同。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1549

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1549

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

236

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

127

2025.10.17

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

322

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

198

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

322

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

198

2025.07.04

2026春节习俗大全
2026春节习俗大全

本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

189

2026.02.11

热门下载

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

精品课程

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

共94课时 | 9.2万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号