This is the situation where your solution calls for an array of structs that are contiguous in memory but aren't the same size. This happens oftenish in database, os, and compression tech. C99 and gcc have legalized the often used convention:
struct varb {
char *foo;
unsigned char age;
int number_of_bars;
char var[]; // it's something like var[0] in GCC, or var[1] in versions < c99
};
where the last element is actually the start of the variable length piece. In all the C supported implementations of var length structs, we have limitations:- the variable part must be declared last
- the struct may not appear in other structs or arrays
which totally makes sense, but doesn't help us implement a contiguous array of variable length structs. Also, the restriction of having the variable part of the struct come last may waste a lot of space if we have a structure where we would rather optimize the order of the struct ourselves, but that's another post!
Assume we are OK with the limitations of our struct varb, we now need to declare and malloc (or mmap) a char* (to hold all of our data) and lay out our varb structs fairly manually. Once we have found the start of a particular varb struct, we can cast it's char* address to a struct varb* and the compiler then can help us populate or interrogate our data. Note that we will need to keep track of detailed memory usage 'so far' when we are populating as well track padding, alignment of adjacent structs, as well as any reallocation when our struct array needs to grow.