a flexible array member
/ FLEK-suh-bul /
Suppose you want one allocation that holds a small header plus a variable number of bytes right after it — a length plus the data, packed together. Before C99 people faked this with the 'struct hack' by declaring a final array of size 1 and over-allocating. C99 made it official: a flexible array member is an array with NO size declared as the LAST member of a struct, like char data[].
You declare it as the final member only, for example struct buf { size_t len; char data[]; };. The flexible member contributes nothing to sizeof(struct buf) (sizeof counts the struct as if data had length zero). You allocate room for the header plus however many elements you need in a single malloc: malloc(sizeof(struct buf) + n) gives you a struct whose data array you may index from 0 up to n-1. This packs the header and payload into one allocation, with one free() to release both.
It matters for network packets, variable-length records, and cache-friendly single-allocation containers. The honest caveats: a flexible array member must be the LAST member and the struct must have at least one other member; you cannot make an array OF such structs or embed one inside another struct; and you must allocate the extra space yourself — a plain local 'struct buf b;' gives data exactly zero usable elements, so writing to b.data is out-of-bounds undefined behavior.
struct buf { size_t len; char data[]; }; // data[] is the flexible member size_t n = 100; struct buf *b = malloc(sizeof *b + n); // header + 100 bytes, one alloc b->len = n; b->data[0] = 'H'; // indices 0..n-1 are valid free(b); // one free releases both
sizeof ignores data[]; you malloc the header plus your chosen length, and one free releases the whole block.
It must be the LAST member and you must over-allocate; a flexible array member declared without extra malloc'd space has zero usable elements, so indexing it is out-of-bounds undefined behavior.