Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a string allocated with malloc?

Tags:

c

malloc

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())?

like image 716
cdonts Avatar asked Apr 09 '14 19:04

cdonts


People also ask

Can we use malloc for string?

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.

What is the return value of malloc () function?

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.

How do you malloc a string?

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.


1 Answers

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 using malloc(3) if buf is NULL. In this case, the allocated buffer has the length size unless size is zero, when buf is allocated as big as necessary. The caller should free(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.

like image 81
abligh Avatar answered Oct 04 '22 16:10

abligh