What is the proper/preferred way to allocate memory in a C API?
I can see, at first, two options:
1) Let the caller do all the (outer) memory handling:
myStruct *s = malloc(sizeof(s));
myStruct_init(s);
myStruct_foo(s);
myStruct_destroy(s);
free(s);
The _init
and _destroy
functions are necessary since some more memory may be allocated inside, and it must be handled somewhere.
This has the disadvantage of being longer, but also the malloc can be eliminated in some cases (e.g., it can be passed a stack-allocated struct:
int bar() {
myStruct s;
myStruct_init(&s);
myStruct_foo(&s);
myStruct_destroy(&s);
}
Also, it's necessary for the caller to know the size of the struct.
2) Hide malloc
s in _init
and free
s in _destroy
.
Advantages: shorter code, since the functions are going to be called anyway. Completely opaque structures.
Disadvantages: Can't be passed a struct allocated in a different way.
myStruct *s = myStruct_init();
myStruct_foo(s);
myStruct_destroy(foo);
I'm currently leaning for the first case; then again, I don't know about C API design.
Method number 2 every time.
Why? because with method number 1 you have to leak implementation details to the caller. The caller has to know at least how big the struct is. You can't change the internal implementation of the object without recompiling any code that uses it.