gcc (GCC) 4.7.0
c89
Hello,
I am wondering if I am thinking correctly here. When I allocate memory using malloc. malloc will return a pointer to a size in memory.
So before I allocate my memory all pointers will have the value NULL.
Using this code snippet:
struct address *db_row = NULL;
db_row = malloc(sizeof(struct address));
db_row->name = malloc(sizeof(char) * 10);
db_row->email = malloc(sizeof(char) *10);
free(db_row->name);
free(db_row->email);
free(db_row);
I have done this in the gdb debugger for db_row before allocating memory:
(gdb) p db_row
$20 = (struct address *) 0x0
(gdb) p *db_row
Cannot access memory at address 0x0
Which is correct, as no memory address has been allocated.
After I allocate memory I get the following when I do the same:
(gdb) p db_row
$25 = (struct address *) 0x602310
(gdb) p *db_row
$26 = {id = 0, set = 0, name = 0x0, email = 0x0}
However, after I have free the memory I still get the same memory address, should it not be NULL as in the first case before allocating any memory?
After freeing the memory:
(gdb) p db_row
$28 = (struct address *) 0x602310
(gdb) p *db_row
$27 = {id = 6300480, set = 0, name = 0x602330 "", email = 0x602350 " #`"}
As you can see its still pointing to the same memory location, is this correct?
Finally, I added this at the end to see if I could do a double free:
if(db_row != NULL) {
free(db_row);
}
if(db_row != NULL) {
free(db_row);
}
I get a stack dump on the second call to free. But as a safety measure should you always check to make sure you are not trying to do a double free?
It it worth setting the pointers to NULL after free them?
db_row = NULL;
Many thanks for any suggestions,
Answer
But as a safety measure should you always check to make sure you are not trying to free a NULL pointer?
Calling free()
with a NULL
pointer is safe and nothing occurs. Calling free()
does not NULL
the pointer, you may do this explicitly. NULL
ing a pointer after calling free()
would prevent the double free on the same pointer variable:
/* Assuming 'db_row' is referring to a valid address
at this stage the following code will not result
in a double free.*/
free(db_row);
db_row = NULL;
free(db_row);
If another pointer variable is pointing to the same address and is passed to free()
then a double free still occurs.
Just because a pointer is not-NULL
does not guarantee that it points to a valid address. It is the programmer's responsibility to ensure double free()
s do not occur. NULL
ing pointer variables after a call to free()
helps but does not provide a guarantee as multiple pointer variables can be pointing at the same address.
But as a safety measure should you always check to make sure you are not trying to do a double free?
There is no way to query a pointer variable to determine if the memory at the address that it holds has already been free()
d. A pointer variable holds an address, nothing more.
No comments:
Post a Comment