柔性数组(Flexible Array Member)

← C语言知识地图


核心:结构体最后一个成员声明为不完整数组,实际大小在运行时按需分配。

定义规则

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
内存连续性✅ 一次分配,连续内存❌ 结构体 + 指针指向区,两次分配
释放一次 freefree(ptr->data),再 free(ptr)
缓存友好✅ 数据紧邻结构体❌ 可能分散
sizeof不计入计入指针大小