Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asprintf - when to use free()?

Tags:

c

free

asprintf says

The functions asprintf() and vasprintf() are analogs of sprintf(3) and vsprintf(3), except that they allocate a string large enough to hold the output including the terminating null byte, and return a pointer to it via the first argument. This pointer should be passed to free(3) to release the allocated storage when it is no longer needed.

Here is my C code

void function(){
    char *out = NULL;
    int parts[16] = {1,2,05,003};
    asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
  //  free(out);
}

int main(void){
    function();
    return 0;
}

When the function is monitored on the debug mode, I see that the variable is already destroyed when it returns from the function. Why I don't need to free() the code above?

Could you tell me in what cases of asprintf I need to use free?

btw, I have "gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)"

enter image description hereenter image description here

like image 591
Angs Avatar asked Jun 28 '13 13:06

Angs


People also ask

Do you need to free Asprintf?

You need to free() that memory before you lose the address and it becomes forever beyond your reach.

Is Asprintf safe?

As with snprintf, it's easy to forget to check the result, but at least with snprintf the result is always a safe string. With asprintf, not checking the result or doing it incorrectly will lead to undefined behaviour.

What is Asprintf in C?

The asprintf (mnemonic: "allocating string print formatted") command is identical to printf , except that its first parameter is a string to which to send output. It terminates the string with a null character. It returns the number of characters stored in the string, not including the terminating null.

What library is Asprintf in?

The asprintf() and vasprintf() functions are widely used to get things done in C without buffer overflows. One problem with them is that they are not actually standard (they are not in C11). That said, they are widely implemented; they are in the GNU C library and in the *BSDs (including Apple's).


2 Answers

You need to call free().

The variable leaves the scope, so the actual value of the variable (the address that free() needs) is lost at that point, creating a memory leak.

The free() function is interested in the address of memory previously returned by malloc() or some other heap allocation call, not at all in your particular variable.

You could do:

char *out = NULL, *a, *b, *c, *d, *e;
int parts[16] = {1,2,05,003};
asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
a = b = c = d = e = out;

and that's just five more variables holding copies of the same address going out of scope. The heap subsystem (as reached through the malloc()/free() calls) knows nothing about this, of course.

like image 58
unwind Avatar answered Oct 10 '22 21:10

unwind


It seems you don't quite understand what pointers are, what local variables are, and what allocating memory does.

In your function() you have a variable out. You've declared that it is a char pointer.

You're passing a pointer to that variable to asprintf(). This is so asprintf can allocate some memory on the heap, and store the address of that memory location in out. This is called a "pointer to a pointer" and why the signature of asprintf() appears as asprintf(char **ret, .. ) - note the double **

out now contains the address of the allocated memory. You then leave function(). out ceases to exist because it's a local variable and only exists on the stack. The address that was previously contained in it is lost but the memory that was allocated on the heap that address referred to remains allocated ... and you have a memory leak.

You need to free() that memory before you lose the address and it becomes forever beyond your reach.

like image 44
Brian Roach Avatar answered Oct 10 '22 21:10

Brian Roach