I'm creating a function that returns a string. The size of the string is known at runtime, so I'm planning to use malloc()
, but I don't want to give the user the responsibility for calling free()
after using my function's return value.
How can this be achieved? How do other functions that return strings (char *
) work (such as getcwd()
, _getcwd()
, GetLastError()
, SDL_GetError()
)?
malloc() returns a void* pointer to a block of memory stored in the heap. Allocating with malloc() does not initialize any string, only space waiting to be occupied.To add a null-terminating character, you either have to do this yourself, or use a function like scanf() , which adds this character for you.
Return value malloc returns a void pointer to the allocated space, or NULL if there's insufficient memory available. To return a pointer to a type other than void , use a type cast on the return value.
Space is allocated by calling malloc with the number of bytes needed (for strings this is always one more than the maximum length of the string to be stored): char *pc = malloc(MAXSTR + 1) ; // can hold a string of up to MAXSTR characters.
Your challenge is that something needs to release the resources (i.e. cause the free()
to happen).
Normally, the caller frees the allocated memory either by calling free()
directly (see how strdup
users work for instance), or by calling a function you provide the wraps free
. You might, for instance, require callers to call a foo_destroy
function. As another poster points out you might choose to wrap that in an opaque struct
, though that's not necessary as having your own allocation and destroy functions is useful even without that (e.g. for resource tracking).
However, another way would be to use some form of clean-up function. For instance, when the string is allocated, you could attach it to a list of resources allocated in a pool, then simply free the pool when done. This is how apache2
works with its apr_pool
structure. In general, you don't free()
anything specifically under that model. See here and (easier to read) here.
What you can't do in C (as there is no reference counting of malloc()
d structures) is directly determine when the last 'reference' to an object goes out of scope and free it then. That's because you don't have references, you have pointers.
Lastly, you asked how existing functions return char *
variables:
Some (like strdup
, get_current_dir_name
and getcwd
under some circumstances) expect the caller to free.
Some (like strerror_r
and getcwd
in under other circumstances) expect the caller to pass in a buffer of sufficient size.
Some do both: from the getcwd
man page:
As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc)
getcwd()
allocates the buffer dynamically usingmalloc(3)
ifbuf
isNULL
. In this case, the allocated buffer has the lengthsize
unlesssize
is zero, whenbuf
is allocated as big as necessary. The caller shouldfree(3)
the returned buffer.
Some use an internal static buffer and are thus not reentrant / threadsafe (yuck - do not do this). See strerror
and why strerror_r
was invented.
Some only return pointers to constants (so reentrancy is fine), and no free is required.
Some (like libxml
) require you to use a separate free
function (xmlFree()
in this case)
Some (like apr_palloc
) rely on the pool technique above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With