5
votes

Qu'arrive-t-il à un pointeur vers un autre pointeur lorsque le premier est libéré?

J'ai fait une simulation d'une pile en utilisant malloc pour créer un tableau d'éléments MAX et l'assigner à un pointeur. J'ai ensuite fait un deuxième pointeur pointant vers le premier, pour pouvoir naviguer d'avant en arrière, en exécutant des push et des pop.

free (stack);

Au final, je supprime le pointeur contenant le tableau, en utilisant

int * stack= (int *) malloc(MAX * sizeof(*stack));
int * stack_ptr = stack;

Après avoir supprimé le tableau ( stack ), stack_ptr pointe vers une adresse sans contenu, non?

Cela peut-il provoquer une fuite de mémoire ou tout autre problème, même si le programme se termine exactement après?


4 commentaires

Ce n'est pas un pointeur vers un autre pointeur, mais une copie du pointeur obtenu de malloc. Un seul bloc de mémoire existe et vous pouvez utiliser n'importe quelle copie de son pointeur. C'est la valeur que vous passez à free qui compte, pas la variable dans laquelle il est stocké. Après cela, vous ne devez pas déréférencer le pointeur, quelle que soit la variable dans laquelle il est stocké .


Google "pointeur suspendu" - ne vous inquiétez pas - c'est un terme informatique authentique et sûr pour le travail ;-)


free (stack_ptr) libérera également le bloc. Et tout comme vous n'utilisez pas stack_ptr pour accéder au tas après la libération du bloc auquel il fait référence, tout autre pointeur référençant ce bloc ne doit pas accéder au bloc libéré.


Un exemple de pointeur vers un autre pointeur serait int ** stack_ptr = & stack;


4 Réponses :


1
votes

Aucune fuite de mémoire car vous avez fait une copie du pointeur. Ainsi, le pointeur stack_ptr pointe vers l'espace non alloué.

Si vous voulez lire le contenu pointé par stack_ptr après votre code, cela provoquera une erreur de segmentation car vous avez libéré l'espace alloué par votre malloc.


0 commentaires

1
votes

https://en.wikipedia.org/wiki/Dangling_pointer

Vous pouvez ou non effectuer une segmentation si vous essayez de le déréférencer, mais il est suspendu. Il n'y a cependant pas de fuite de mémoire. stack_ptr est toujours sur la pile, et sera sauté au retour de la fonction, comme les variables de pile normales. Vous libérez la mémoire vers laquelle il pointe.


0 commentaires

1
votes

Ce n'est pas un pointeur vers un pointeur seulement les deux ont la même valeur. Rien ne se passera pour le second. Il aura toujours la même valeur, mais cette fois, il fera référence à la mémoire non allouée.

c'est le pointeur vers le pointeur (ptr2):

int *ptr1;
int **ptr2 = &ptr1


0 commentaires

2
votes

Après avoir supprimé le tableau (pile), stack_ptr pointe vers une adresse sans contenu, non?

Après free (stack); , tenter d'exécuter * stack_pt est un comportement indéfini (UB). Le contenu pointé vers stack_pt peut être bon, mauvais ou laid ou simplement provoquer un plantage du code. C'est à UB d'essayer de le découvrir.

Cela peut-il provoquer une fuite de mémoire ou tout type de problème, même si le programme se termine exactement après?

Avoir une copie inchangée de l'ancien pointeur valide dans stack_pt en lui-même n'est pas une fuite ni UB. N'utilisez simplement pas stack_pt .


Souvent, après la libération, il est recommandé de NULL le (s) pointeur (s). P >

// int * stack= (int *) malloc(MAX * sizeof(*stack));
int *stack =  malloc(sizeof *stack * MAX);

À part: il est recommandé d'allouer à la taille de l'objet référencé, pas au type et de renoncer à la conversion inutile.

int * stack= (int *) malloc(MAX * sizeof(*stack));
int * stack_ptr = stack;
...
free (stack);
stack = NULL;
stack_ptr = NULL;

0 commentaires