free usage (revisited)

A

ashok.anbalan

I wrote a simple program to get a feel of the way free() works.


/*free/malloc usage.*/
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
// LOCATION_1
// int i =5;

int *ip= (int *) malloc (sizeof(int));

//LOCATION_2
int i = 5;
ip = &i;
printf ("Address of i is: %p \n", ip);
free(ip);
printf ("Address of i (after calling free) is: %p \n", ip);
ip = NULL;
printf ("Address of i (after assigning it to NULL) is: %p \n", ip);
return 0;
}

I use gcc on cygwin & here are two things that I observed:

1. If the statement "int i =5" at LOCATION_1 is uncommented & instead
the assignment at LOCATION_2 is commented, this program core dumps. I
am not sure why this happens.

2. Even after calling free(), the address printed is same as the one
before calling free. Hence, my understanding is that the free() call
suggests that memory be returned back to the system, although the
pointer variable ip will become unusable only where the scope of ip
logically ends. IS this understanding correct?

Can someone clarify these?

Thanks,
Ashok
 
M

manoj1978

I wrote a simple program to get a feel of the way free() works.


/*free/malloc usage.*/
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
// LOCATION_1
// int i =5;

int *ip= (int *) malloc (sizeof(int));

//LOCATION_2
int i = 5;
ip = &i;
printf ("Address of i is: %p \n", ip);
free(ip);
free only the memory you allocated using malloc,calloc,realloc.
it is an undefined behaviour.
printf ("Address of i (after calling free) is: %p \n", ip);
ip = NULL;
printf ("Address of i (after assigning it to NULL) is: %p \n", ip);
return 0;
}

I use gcc on cygwin & here are two things that I observed:

1. If the statement "int i =5" at LOCATION_1 is uncommented & instead
the assignment at LOCATION_2 is commented, this program core dumps. I
am not sure why this happens.
see above comment.
it is looking for a header and accessing some random area.
2. Even after calling free(), the address printed is same as the one
before calling free. Hence, my understanding is that the free() call
suggests that memory be returned back to the system, although the
pointer variable ip will become unusable only where the scope of ip
logically ends. IS this understanding correct?
free never changes the pointer passed to it.it frees the memory
only.
it is upto the programmer to modify the pointer.
 
K

Keith Thompson

I wrote a simple program to get a feel of the way free() works.


/*free/malloc usage.*/
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
// LOCATION_1
// int i =5;

int *ip= (int *) malloc (sizeof(int));

The cast is unnecessary and could potentially hide errors. This is
better written as:

int *ip = malloc(sizeof *ip);

(By applying sizeof to *ip rather than to type int, you avoid errors
if the type of ip is changed later.)

You should also check whether the malloc() call failed, but we can
probably ignore that in a small test program.
//LOCATION_2
int i = 5;
ip = &i;

You've just leaked memory. ip held the address of the memory
allocated by malloc(); by assigning a new value to ip, you've thrown
away that address and made it impossible to free it. This would be a
design flaw in a real program; in a small test case, it doesn't really
matter.
printf ("Address of i is: %p \n", ip);

The %p format expects a void*; you should cast ip to void*:

printf ("Address of i is: %p\n", (void*)ip);

(This is one of the few cases where casting is necessary.)
free(ip);

Since ip no longer holds the value returned by malloc(), you can't
legally pass it to free(). Doing so invokes undefined behavior.
printf ("Address of i (after calling free) is: %p \n", ip);

Even if the free() call had been valid, using the value of ip after
calling free(ip) would invoke undefined behavior. Even though the
value (or at least the representation) of ip isn't changed by free(),
that value becomes an "indeterminate value", since it points (or
rather pointed) to an object that no longer exists.

(In most cases, the undefined behavior will show up as the printf()
call behaving exactly as you expect it to, printing the same pointer
value that was displayed before the free(). It's still undefined
behavior.)
ip = NULL;
printf ("Address of i (after assigning it to NULL) is: %p \n", ip);
return 0;
}

The message is misleading; after you set ip to NULL, what you're
printing isn't the address of i.
 
S

sunglo

Keith said:
The %p format expects a void*; you should cast ip to void*:

printf ("Address of i is: %p\n", (void*)ip);

(This is one of the few cases where casting is necessary.)

Why doesn't automatic conversion happen here, like in many
other calls to functions that expect a void *, where the
explicit cast is not needed?

Thanks
 
K

Keith Thompson

Why doesn't automatic conversion happen here, like in many
other calls to functions that expect a void *, where the
explicit cast is not needed?

Because printf() takes a variable number and type of arguments.

The declaration of printf() is:

int printf(const char * restrict format, ...);

(You can ignore the "const" and "restrict" for now (the latter is
C99-specific).)

The compiler knows that the first argument is of type char*, but it
doesn't know that the second argument is of type void*. If it did, it
could do the implicit conversion from char* to void*. (The
information is in the format string, but the compiler can't use that;
the format string could be a variable rather than a literal.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,427
Latest member
HildredDic

Latest Threads

Top