柔性数组(Flexible Array Member)
核心:结构体最后一个成员声明为不完整数组,实际大小在运行时按需分配。
定义规则
typedef struct {
int len; // 至少一个其他成员
int data[]; // 柔性数组,必须是最后一个成员
} FlexArray;- C99 标准,
data[]也可写成data[0](GNU 扩展,兼容旧代码) - 结构体必须有至少一个前置成员,且柔性数组成员的个数不限。
sizeof 不计入
sizeof(FlexArray) == sizeof(int); // data 占用 0 空间典型用法:堆分配
int n = 100;
FlexArray *fa = malloc(sizeof(FlexArray) + n * sizeof(int));
fa->len = n;
fa->data[0] = 42; // 合法访问申请时 sizeof 只覆盖结构体固定部分,柔性数组的空间需手动叠加。
栈上分配
alloca
FlexArray *fa = alloca(sizeof(FlexArray) + n * sizeof(int));固定缓冲区 + 强转
char buf[sizeof(FlexArray) + n * sizeof(int)];
FlexArray *fa = (FlexArray *)buf;对比:指针方案 vs 柔性数组
柔性数组 int data[] | 指针 int *data | |
|---|---|---|
| 内存连续性 | ✅ 一次分配,连续内存 | ❌ 结构体 + 指针指向区,两次分配 |
| 释放 | 一次 free | 先 free(ptr->data),再 free(ptr) |
| 缓存友好 | ✅ 数据紧邻结构体 | ❌ 可能分散 |
| sizeof | 不计入 | 计入指针大小 |