2010-02-15 4 views
1

main() appelle la fonction Call_By_Test() avec le paramètre argument First Node. J'ai libéré le premier nœud dans Call_By_Test() mais l'adresse du premier nœud n'est pas libérée dans main(), pourquoi?Question sur l'appel-par-référence?

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; 


} 

Sortie: première valeur de pointeur 0x804b008 j'ai libéré d'abord NODE Call-By-Test(), mais pourquoi premier pointeur de nœud a la valeur 0x804b008

+0

@SIVA: Si vous êtes satisfait des réponses à certaines de vos 6 dernières questions, vous devez les accepter (en cliquant sur la coche creuse). – kennytm

+0

Vous faites deux choses différentes dans 'Call_By_Test': vous appelez' free (ptr) 'et' ptr = NULL'. Lequel des deux attendez-vous d'affecter le 'first' dans main()? – MSalters

+2

Je me demande toujours pourquoi la plupart des gens commencent à apprendre C++ à partir du sous-ensemble C ... –

Répondre

5

Depuis la question est étiqueté C++, je refactoriser à:

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

Cela transmet la référence de passage sans déréférences supplémentaires. Toutes les solutions qui proposent de passer un pointeur sur le pointeur (void Call_By_Test(mynode ** first)) utilisent une sémantique pass-by-value dans un pointeur vers la variable pointeur. Tandis que vous pouvez le faire en C++, le passage par référence est plus clair.

+1

+1. Bon point. Même si vous lisez le code, il crie "C" !!! Je n'ai même pas remarqué la balise C++ :) – neuro

7

La réponse est que vous n'êtes pas en utilisant le renvoi par référence. Vous passez un pointeur par valeur - et ce n'est pas la même chose. Cela signifie que vous verrez des changements dans les données auxquelles le pointeur fait référence, mais que modifier la valeur de first lui-même dans la méthode Call_By_Test ne fait rien.

3

Dans la fonction

void Call_By_Test(mynode * first) 

premier est efficacement une variable locale de la fonction. Le changer ne changera pas l'état du reste du programme. Vous avez besoin d'une référence à un pointeur ou un pointeur vers un pointeur:

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

et l'appeler:

Call_By_Test(& first); 
0

Si vous free un pointeur (comme 0x804b008), cela ne change pas la bits dans le pointeur lui-même. Il permet simplement à la bibliothèque C++ d'enregistrer que la mémoire à l'adresse pointée n'est plus utilisée et peut être recyclée. Dans votre cas, lorsque vous imprimez 0x804b008, la mémoire à l'adresse 0x804b008 peut être réutilisée par la bibliothèque C++.

1

Quand vous faites:

void Call_By_Test(mynode * first) 

Vous copiez d'abord, afin que vous puissiez travailler sur ce qui se trouve dans la première, mais vous ne pouvez pas changer l'adresse d'abord car il est une copie.

Si vous voulez changer la première valeur, alors vous devriez avoir une fonction comme ceci:

void Call_By_Test(mynode ** first) 

ou

void Call_By_Test(mynode & first) 

qui vous permettent d'accéder d'abord l'argument comme si elle était l'original variable (et non une copie de la fonction principale)