1 votes

Gestion de la mémoire C/Glib {pas de référence pendante > pourquoi!??}

J'ai un programme qui appelle une fonction avec des arguments non définis, comme ceci :

#include 
... /* code */
int main () { 
  GArray *garray = g_array_new (FALSE, FALSE, sizeof (char *));
  /* le code ci-dessus initialise la GArray, et indique que la garray attend un pointeur vers char. */
  function_name (garray, "arg2", "arg3" /* et ainsi de suite ... */);
  ... /* code */
}

notez que, les args entre " " sont des chaînes de caractères, donc, dans la function_name :

static void function_name (GArray *garray, ...) {
  ... /* code */
  char *data;
  data = va_arg (garray, gchar *);
  g_array_append_val (garray, data);
  ... /* code */
}

   Donc, si data pointe vers un argument dans va_list, lorsque la fonction retourne, théoriquement le data pointé, devient invalide, et donc dans garray aussi.
(causant une référence pendante, car le pointeur data pointe vers une adresse mémoire non réservée).

   mais cela ne semble pas se produire, le programme s'exécute bien. pourquoi ? et, en C, les arguments passés aux fonctions sont stockés dans la pile, donc, data pointe-t-il vers la vie en pile en effet mémoire?

merci beaucoup.

4voto

caf Points 114951

Lorsque vous introduisez une constante de chaîne dans un programme C, un objet anonyme et non modifiable, avec une durée de stockage statique est créé. "La durée de stockage statique" signifie qu'il vit pendant la durée du programme.

Donc lorsque vous avez ceci dans votre code:

nom_de_la_fonction (gtableau, "arg2", "arg3" /* et ainsi de suite ... */);

Les chaînes "arg2" et "arg3" sont des constantes de chaîne - elles existent quelque part dans la mémoire du programme, pendant la durée du programme. Souvent elles sont stockées dans un segment de texte, de la même manière que le code du programme lui-même l'est.

Ce qui est effectivement passé à la fonction nom_de_la_fonction() - probablement sur la pile - sont des pointeurs vers ces constantes de chaîne. Et c'est ce que votre GTableau finit par stocker - des pointeurs vers ces constantes de chaîne.

(Notez qu'une chaîne utilisée comme un initialiseur de tableau n'est pas une constante de chaîne).

0voto

Dave Gamble Points 3245

Une des trois choses est vraie:

Soit : 1) g_array_append_val fait une copie de la chaîne.

Ou : 2) dès que la pile est à nouveau écrasée, les choses vont se casser.

void burn_stack(int size)
{
   char data[8]={0,0,0,0,0,0,0,0};
   size-=8;
   if (size>0) burn_stack(size);
}

Essayez d'appeler burn_stack(256); après function_name, et voyez si les choses continuent à fonctionner.

Ou : 3) Vous utilisez des const char "string"s, qui sont stockés dans la section des chaînes de l'exécutable, et non dans le tas ni dans la pile, donc ils persisteront indéfiniment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X