2010-02-15 3 views
1

main() вызывает функцию Call_By_Test() с параметром параметра First Node. Я освободил первый узел в Call_By_Test(), но адрес первого узла не освобожден в main(), почему?.Вопрос по вызову по ссылке?

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; 


} 

Выход: первое значение указателя 0x804b008 Я освободил первый УЗЕЛ в Call-By-Test(), но почему первый указатель узла имеет значение 0x804b008

+0

@SIVA: Если вас устраивают ответы на некоторые из ваших последних 6 вопросов, вы должны их принять (нажав на полую галочку). – kennytm

+0

Вы делаете две разные вещи в 'Call_By_Test': вы называете' free (ptr) 'и' ptr = NULL'. Какой из двух вы ожидаете повлиять на «first» в main()? – MSalters

+2

Я все еще удивляюсь, почему большинство людей начинают изучать C++ из подмножества C ... –

ответ

5

Поскольку вопрос отмечен C++, я бы реорганизовал на:

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

Это передает пропускную информацию без дополнительных разностей. Все решения, предлагающие передачу указателя на указатель (void Call_By_Test(mynode ** first)), используют семантику pass-by-value в указателе на переменную-указатель. Хотя вы можете сделать это на C++, передача по ссылке более ясная.

+1

+1. Хорошая точка зрения. Даже если вы читаете код, он кричит «C» !!!. Я даже не заметил тег C++ :) – neuro

7

Ответ в том, что вы не используя pass-by-reference. Вы передаете указатель по значению - и это не одно и то же. Это означает, что вы увидите изменения в данных, на которые ссылается указатель, но изменение значения first в методе Call_By_Test ничего не делает.

3

В функции

void Call_By_Test(mynode * first) 

первый фактически является локальной переменной функции. Изменение его не изменит состояние остальной части программы. Вам нужна ссылка на указатель или указатель на указатель:

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

и назвать его:

Call_By_Test(& first); 
0

Если вы free указатель (например, 0x804b008), что не меняет бит в самом указателе. Он просто позволяет библиотеке C++ записывать, что память на указанном адресе больше не используется и может быть переработана. В вашем случае, когда вы печатаете 0x804b008, память по адресу 0x804b008 доступна для повторного использования библиотекой C++.

1

Когда вы делаете:

void Call_By_Test(mynode * first) 

Вы копируете первый, так что вы можете работать на том, что находится в первом, но вы не можете изменить адрес первого, так как он является копией.

Если вы хотите изменить значение первого, то вы должны иметь такую ​​функцию:

void Call_By_Test(mynode ** first) 

или

void Call_By_Test(mynode & first) 

, которые позволяют получить доступ к аргумент первой, как если бы это был оригинал переменная (а не копия основной функции)

Смежные вопросы