Sounds like you may be looking for the "flexible array member" feature whereby an incomplete array is placed at the end of a structure:
struct ListNode {
struct ListNode *next;
char data[];
};
This is allocated like:
struct ListNode *node = malloc(sizeof *node + data_size_bytes);
Then we can store values in node->data[i]
for i
from 0
to data_size_bytes - 1
. The whole structure and data are in one linear block.
Note that a structure with a flexible member can't be used as an array element type.
Before the ISO C standard added the flexible array member in 1999, this was done as a popular "struct hack" using an array of size 1. If you're constrained to working in C90 it goes like this:
struct ListNode {
struct ListNode *next;
char data[1];
};
Now sizeof ListNode
includes the one element array, and quite likely padding for alignment. For instance on a system with four byte pointers, the size is quite likely eight. If we use the same malloc
line, we will allocate excess memory. The right malloc
expression to use for the C90 struct hack:
#include <stddef.h>
struct ListNode *node = malloc(offsetof(struct ListNode, data) + data_size_bytes);
Unlike the flexible array member feature, the struct hack doesn't have formally well-defined behavior; it's just something that "works if it works".