Otherwise I prefer libraries that allow setting the allocation function at least.
Otherwise I prefer libraries that allow setting the allocation function at least.
That's why even people knew, many C APIs still return dynamic allocated objects or simply let you inject malloc / free if you want more control.
This is a roundabout way to say: if you aspired to provide APIs with zero dynamic allocation, go ahead. But if you find yourself struggling with more complicated code as a result, think about just letting a little bit dynamic allocations may help.
Caller provides memory and function fails if there is to little memory, but writes the the required (variable) amount of memory to an `out length` pointer.
Effectively leading to a common pattern of:
1. call function with empty buffer (or buffer or arbitrary size)
2. allocate buffer
3. call function again with properly sized buffer
4. add a loop if between 1 & 3 the required buffer size can change
its fascinating how well it works for some of it's common use cases and how subtle but badly broken it can be for other use cases :=)
https://docs.microsoft.com/en-us/windows/win32/seccrypto/exa...
They managed to mix both patterns into a ghastly 9 function call!
The example above speaks for itself but I kind of see the "we provide you with memory you need to call 'FreeX' on" and the "call the function twice, once to find out how much memory you need to allocate" patterns to be equally annoying to use.
Callers allocate the right size no matter what OS version, and can only see the fields exposed on the version they were built for.
Anyway, the whole "caller allocates" concept doesn’t work too well in the particular case of `gethostbyname`, which as the author mentions, is a complex struct containing several pointers and double pointers, with a potentially unlimited number of different-length allocations one would have to make!
> If this structure is dynamically allocated by gethostbyname() and returned to the caller, either you need an additional API function to free it or you have to commit to what fields in the structure have to be freed separately, and how
With your approach, wouldn't you need to free all the fields in the structure separately as well? Because, what's the difference between the library allocating the memory -with the problems the article points out- and allocating it yourself?