1

Today I was trying to call strerror POSIX function. It returns a char*, and now I am not sure whether to free it or not to free it.

The application shall not modify the string returned.

I think the returning pointer is supposed to be a pointer to a internal static buffer, and in that case, I should never touch it. But, it just says "do not modify", and doesn't talk about memory ownership at all. I am confusing. I would assume "no touch" as "system owns, caller borrows", but still I am not confident because it's just my inference rather than a promise or definition.

I am not very familiar with C/POSIX programming. I think there must be a well established convention or explicit rules for this, but I couldn't find any.

What is memory ownership rule of C/POSIX functions?

eonil
  • 83,476
  • 81
  • 317
  • 516
  • 3
    It doesn't say "you need to free (the result of `strerror()`)" so you don't free it. If it tells you it is allocated "as if by a call to `malloc()`" or something similar, you need to free it. Basically, there isn't a single rule for everything — except "read the manual page for the function you're calling". – Jonathan Leffler Sep 30 '18 at 05:19
  • `strerror` is standard C, not just POSIX. – melpomene Sep 30 '18 at 05:25
  • There are no tricks. As @JonathanLeffler explained, the man-page will make clear whether the user is responsible for freeing a resulting string or block of memory. In the absence of an explicit statement making clear the user is responsible, don't pass the resulting pointer to `free` (if you start experimenting, an immediate SegFault, or double-free memory corruption, will also show you the error in your ways...) – David C. Rankin Sep 30 '18 at 06:17

1 Answers1

1

The convention is that you do not free the pointer (or write to it) unless the description of the function returning it tells you you should free it. However, the POSIX idiom to express that is a bit strange, so it is easy to become confused.

For example, for strdup and strndup it's:

The returned pointer can be passed to free(). […] duplicating the provided s in a new block of memory allocated as if by using malloc()

For realpath, it's this:

If resolved_name is a null pointer, the generated pathname shall be stored as a null-terminated string in a buffer allocated as if by a call to malloc().

Contrast this with the documentation of getaddrinfo or fopen, which does not use such language. Instead you are expected to use the specific deallocation functions (freeadrinfo and fclose).

In short, each time POSIX says that a pointer can be passed to free or a pointer to memory allocated as if by using malloc(), it actually means you need to free that pointer if you want to avoid a memory leak. Otherwise, you are not allowed to free the pointer.

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92