Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)); } 
like image 550
Paul Avatar asked Jun 01 '15 09:06

Paul


People also ask

What functions set errno?

To detect an error, an application must set errno to 0 before calling the function and check whether it is nonzero after the call. Affected functions include strcoll() , strxfrm() , strerror() , wcscoll() , wcsxfrm() , and fwide() . The C Standard allows these functions to set errno to a nonzero value on success.

How does errno get set?

The <errno. h> header file defines the integer variable errno, which is set by system calls and some library functions in the event of an error to indicate what went wrong.

Does Ferror set errno?

fread does not set errno (as you have discovered), and as such you cannot really determine much about a specific error state; only that there is one. The exact nature of the error is generally implementation-dependent. There is no C standard-library-based portable way to gather it .

Does printf set errno?

printf doesn't set errno , it only returns a negative number.


1 Answers

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; 
like image 160
Sander De Dycker Avatar answered Sep 28 '22 16:09

Sander De Dycker