In a response elsewhere, I found the following snippet:
In general it is nicer in C to have the caller allocate memory, not the callee - hence why str
The main advantage of having the caller allocate the memory is that it simplifies the interface, and it's completely unambiguous that the caller owns the memory. As your create/destroy example shows, the simplification is not very great.
I prefer the create/destroy convention established by Dave Hanson in C Interfaces and Implementations:
struct foo *foo_new(...); // returns result of malloc()
void foo_free(struct foo **foop); // free *foop's resources and set *foop = NULL
You follow the convention thus:
struct foo *a = foo_new();
...
foo_free(&a);
// now `a` is guaranteed to be NULL
This convention makes it a little less likely you will leave a dangling pointer.