Say I have a struct
struct GRAPH {
NODE* nodes[];
}
With a dynamic size for nodes[]. I also have
struct NODE {
char filename[40];
struct NODE* links[];
}
I will know how many links and nodes I need at runtime, and can calculate total required space. I know that running malloc() is runtime-costly, so doing a malloc() for nodes[], then adding the pointer from malloc() for each node would be bad.
I presume I will have to call malloc() for the total size of GRAPH, then manually handle pointers from this space, using a char* (1 byte) and saving offsets. Do I need to allocate for and handle null terminators at the end of each links[] (i.e. use calloc() with a larger size)? Is there a better way to be going about this?
You could do what you describe, but using malloc isnt inherently bad. In fact its not a problem the vast majority of the time. Depending on your platform and what your code will do with the graph, malloc is unlikely to be the performance bottleneck in your code.
In a HPC context for example, say it takes a few fractions of a second to allocate a large graph, you may then easily spend 1000x as long actually executing whatever your code is designed to do. That is probably what you should optimise.
That being said, if you did choose to make your own allocator you could use null terminators like you say, or if you knew how many of each structure you needed you could just allocate exactly what you need.