views:

120

answers:

5

main() calls Call_By_Test() function with argument parameter First Node. I have freed the First Node in Call_By_Test() but First node address not freed in main(), why ?.

typedef struct LinkList{
int data;
struct LinkList *next;
}mynode;

void Call_By_Test(mynode * first)
{
        free(first->next);
        first->next = (mynode *)NULL;
        free(first);
        first = (mynode *)NULL;
}
int main()
{
mynode *first;

first = (mynode *)malloc(sizeof(mynode));
first->data = 10;
first->next = (mynode *)NULL;

cout<<"\n first pointer value before free"<<first<<endl;

Call_By_Test(first);
// we freed first pointer in Call_By_Test(), it should be NULL
if(first != NULL)
        cout<< " I have freed first NODE in Call-By-Test(), but  why first node pointer has the value "<<first<<endl;


}

Output: first pointer value 0x804b008 I have freed first NODE in Call-By-Test(), but why first node pointer has the value 0x804b008

+7  A: 

The answer is that you're not using pass-by-reference. You're passing a pointer by value - and that's not the same thing. That means you'll see changes in the data that the pointer refers to, but changing the value of first itself within the Call_By_Test method does nothing.

Jon Skeet
+3  A: 

In the function

void Call_By_Test(mynode * first)

first is effectively a local variable of the function. Changing it will not change the state of the rest of the program. You need a reference to a pointer or a pointer to a pointer:

void Call_By_Test(mynode ** first)
{
        free((*first)->next);
        (*first)->next = NULL;
        free(*first);
        *first = NULL;
}

and to call it:

Call_By_Test( & first );
anon
A: 

If you free a pointer (such as 0x804b008), that doesn't change the bits in the pointer itself. It merely allows the C++ library to record that the memory at the pointed-to address is no longer in use, and can be recycled. In your case, when you print 0x804b008,the memory at address 0x804b008 is available for reuse by the C++ library.

MSalters
+1  A: 

When you do:

void Call_By_Test(mynode * first)

You copy first, so you can work on what is located in first but you can not change the address first since it is a copy.

If you want to change the value first then you should have a function like this:

void Call_By_Test(mynode ** first)

or

void Call_By_Test(mynode & first)

which allow you to access the argument first as if it was the original variable (and not a copy from the main function)

Phong
+5  A: 

Since the question is tagged c++, I would refactor to:

void Call_By_Test( mynode *& first ) // rest of code remains the same

That conveys the pass-by-reference without extra dereferences. All the solutions that propose passing a pointer to the pointer (void Call_By_Test( mynode ** first )) are using pass-by-value semantics in a pointer to the pointer variable. While you can do this in C++, pass-by-reference is clearer.

David Rodríguez - dribeas
+1. Good point. Even if when you read the code it shouts "C" !!!.I even did not notice the C++ tag :)
neuro