struct成员顺序影响内存占用:编译器按对齐要求填充字节,大成员前置可减少padding;new/malloc仅保证max_align_t对齐(通常16字节),simd等需更高对齐须用aligned_alloc;memcpy可能比字段赋值慢且不安全;packed禁用padding但引发未对齐访问风险。

struct 成员顺序怎么影响内存占用?
编译器给 struct 填充字节(padding)是为了让每个成员按自身对齐要求起始。成员排布越松散,填充越多,结构体总大小越大。
- 把大成员(如
double、long long)放在前面,小成员(如char、bool)往后挪,能显著减少 padding - 反例:
struct { char a; double b; char c; }占 24 字节(a 占 1,补 7;b 占 8;c 占 1,补 7) - 优化后:
struct { double b; char a; char c; }占 16 字节(b 占 8;a+c 占 2,补 6 对齐到 16)
对齐不是“省空间”那么简单——CPU 访问未对齐地址可能触发 bus error(ARM/某些 x86 模式),或降速 2–3 倍(x86 大多数情况容忍但慢)。
new 和 malloc 分配的内存一定按最严格对齐吗?
不一定。默认情况下,new 和 malloc 返回的指针保证满足 std::max_align_t 对齐(通常是 16 字节),够用大多数内置类型和常见类。
- 但如果你手动管理 SIMD 类型(如
<strong>m256</strong>)、或自定义分配器,16 字节不够:m256要求 32 字节对齐 - 此时必须用
aligned_alloc(32, size)(C++17)或std::aligned_alloc,不能靠new - 错误写法:
auto p = new char[64]; __m256<em> v = reinterpret_cast<__m256>>(p);</__m256></em>——p不保证 32 字节对齐,运行时报segmentation fault
为什么 memcpy 有时比逐字段赋值还慢?
因为编译器看到字段赋值(尤其是 POD 类型),能内联、重排、甚至向量化;而 memcpy 是黑盒调用,编译器常不敢优化,尤其当结构体含 padding 时:
本文档主要讲述的是关于Objective-C手动内存管理的规则;在ios开发中Objective-C 增加了一些新的东西,包括属性和垃圾回收。那么,我们在学习Objective-C之前,最好应该先了解,从前是什么样的,为什么Objective-C 要增加这些支持。有需要的朋友可以下载看看
立即学习“C++免费学习笔记(深入)”;
-
struct S { int a; char b; }; S x = y;→ 编译器很可能只拷 5 字节(a+b),跳过 padding -
memcpy(&x, &y, sizeof(S));→ 强制拷全部 8 字节(假设 4 字节对齐),多写 3 字节无效内存
更隐蔽的问题:如果结构体含指针或非 trivial 构造函数,memcpy 会破坏语义(浅拷贝陷阱),这不是对齐问题,但常被一起误用。
__attribute__((packed)) 能随便加吗?
不能。它禁用 padding,让结构体紧凑,但代价明确:
- 成员访问可能变慢(CPU 需多次读+拼接)或直接崩溃(ARM 默认不允许多字节未对齐访问)
- 与硬件交互(如 mmap 寄存器、网络包解析)时才考虑用,且要确认目标平台支持
- 加了之后,
sizeof变小,但alignof可能变成 1,后续数组布局、vector 存储都可能出问题 - 示例:
struct <strong>attribute</strong>((packed)) P { uint16_t a; uint32_t b; };→a地址若为奇数,读b在 ARM 上直接 abort
对齐不是“写完跑通就完事”的细节。它藏在 struct 布局、分配方式、拷贝逻辑、跨平台行为底下,一碰就响。真要动,得看准哪一层在响——是 cache line?是 SIMD 指令?还是驱动传参?别光改 packed。








