clinuxmemory-managementfreeerrno

Does free() set errno?


If buf is a malloc() allocated char buffer, does free(buf) set/reset errno?

Let's say I want to write the buffer to a file, and then free it, as I don't need it any more.

Let's say the error policy for the code is to return -1 on an error.

Is this a proper way to write out the buffer and error check without leaking memory?

fputs(buf, somefile);
free(buf);
if (errno) return -1;

Or do I need to consider free possibly setting errno, as in...

fputs(buf, somefile);
if (errno){ 
    free(buf);
    return -1;
}
free(buf);

or, horror of horrors,

do { 
  fputs(buf, somefile);
  int save_errno = errno;
  free(buf);
  errno = save_errno;
  if (errno) return -1;
} while(0);  

where the use of a block allows for a local save_errno to exist in various places should this need to be reused.

All of this would seem to depend on whether free() sets errno.

The linux man page for free() is also the man page for malloc(), etc. It mentions malloc() setting errno, but not free().

The GNU C Library manual page for freeing dynamic memory does not mention whether free() sets errno.

So I wrote a short program to force a write error so I could see if free() reset errno, and it does not. I'm wondering if I should rely upon this result and the fact that free() is so essential that "of course it doesn't set errno."

# See if free() resets errno on a bad write
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
  char * buf = malloc(256);
  snprintf(buf,256,"%s\n", "Hello, World!");

  FILE *badfile;

  badfile = fopen("/dev/null","r");

  fputs(buf, badfile);
  free(buf);
  printf("%d\n", errno);
  printf("%s\n", strerror(errno));
}

Solution

  • POSIX doesn't define free to set errno (although POSIX doesn't currently forbid it, so an implementation might do so - refer to @ArjunShankar's answer for more details). But that's not really relevant to your concern.

    The way you're checking for errors is incorrect. You should check the return value of fputs, and check if it's smaller than 0. If it is, then you can check errno to find out what caused the failure, but that's optional (and should be done before calling any further functions).

    So, something like this should do the trick :

    int result = fputs(buf, somefile);
    /* optionally read errno here if result < 0 (before the free call) */
    free(buf);
    return (result < 0) ? -1 : 0;