Forum Programmation.c Libération de structures dynamiques

Posté par  (site web personnel) .
Étiquettes : aucune
0
3
mai
2005
Bonjour,
J'ai un problème de libération de mémoire et je n'arrive pas à trouver mon erreur.
J'ai un tableau de struct de char (tout ça réparti dans plusieurs fonctions) :
struct Game

{
char * name;
...
}
struct Game* pGames[catCountGames(filename)+1];
...
struct Game * pGame = NULL;
pGame = (struct Game*) malloc (sizeof(struct Game));
pGame->name = (char*) malloc(sizeof(char)*(strlen(ptr)+1));
...
pGames[indice++] = pGame;

Or, quand je veux libérer la mémoire allouée pour name, c'est en fait ma structure qui est des-allouée :
free ((*pGames[i]).name);

ou
free(pGames[i]->name);

me libère pGames[i] mais pas name !! (vu au deboggeur)
Mais qu'est-ce qui m'arrive ? Ou est mon erreur ?

Merci
  • # bizarre

    Posté par  . Évalué à 2.

    C'est vrai que c'est bizarre ! à priori j'aurais fait un truc comme ça aussi ...

    Si tu mets name dans une variable temporaire, ça peut contourner le problème, nan ?

    char *name = pGames[i]->name;
    free(name);


    autrement je vois pas ...

    ;-]
    • [^] # Re: bizarre

      Posté par  . Évalué à 2.

      Pas mieux, c'est curieux en effet...

      Es-tu certain que tes allocations ont bien eu lieu ? Parce que désallouer quelque chose qui n'est pas alloué, je ne sais plus ce qu'il se passe (seg fault, j'imagine).

      À moins d'être absolument sûr de son coup, il est de bon usage de vérifier que les allocations se sont bien déroulées :
      if ((pGame = (struct Game*) malloc (sizeof(struct Game)) == NULL) /* traitement de l'erreur */
      • [^] # Re: bizarre

        Posté par  . Évalué à 3.

        Il se peut que ce soit syntaxiquement correct mais que tes index ne soient pas valides. As-tu bien vérifié les valeurs de i et indice au moment où tu libères la mémoire allouée ? Comme les différents blocs ont tendance à être déclarés les uns derrière les autres en mémoire, il se peut que tu libères le mauvais objet (si par exemple, ton indice commence à 1 au lieu de 0).
  • # La vérité est ailleurs

    Posté par  . Évalué à 3.

    Après simulation, je pense que ton bug se trouve ailleurs.

    ------------------------------------------8<-----------------------------------------

    #include <stdlib.h>
    #include <stdio.h>

    #define NAME "plop"

    typedef struct Game
    {
    char *name;
    int data;
    } game_t;

    int count(void)
    {
    return 42;
    }

    int main(void)
    {
    game_t *games[count()]; /* je savais pas que ça marchait ! */
    game_t *game = NULL;
    const char *plop = NAME;
    int i = 0;

    /* alloue un game */
    game = malloc(sizeof(*game));
    if (game == NULL) { perror("malloc()"); exit(1); }

    game->name = calloc(strlen(NAME) + 1, sizeof(char));
    if (game->name == NULL) { perror("calloc()"); exit(1); }

    /* initialise */
    memcpy(game->name, plop, strlen(plop));
    game->data = 1337;

    /* enregistrement */
    games[i ++] = game;
    printf("Supaire nom : %s\n", games[i - 1]->name);
    printf("data : %i\n", games[i - 1]->data);

    /* suppression */
    free(games[0]->name);

    #ifdef CRASHME
    printf("Supaire nom : %s\n", games[i - 1]->name);
    #endif
    printf("data : %i\n", games[i - 1]->data);

    free(games[0]);

    #ifdef CRASHME
    printf("Supaire nom : %s\n", games[i - 1]->name);
    printf("data : %i\n", games[i - 1]->data);
    #endif

    return 0;
    }

    ------------------------------------------8<-----------------------------------------

    jaguarwan@Jaguar:~$ gcc coincoin.c
    jaguarwan@Jaguar:~$ valgrind --tool=memcheck --leak-check=yes ./a.out
    ==5996== Memcheck, a memory error detector for x86-linux.
    ==5996== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
    ==5996== Using valgrind-2.2.0, a program supervision framework for x86-linux.
    ==5996== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
    ==5996== For more details, rerun with: -v
    ==5996==
    Supaire nom : plop
    data : 1337
    data : 1337
    ==5996==
    ==5996== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
    ==5996== malloc/free: in use at exit: 0 bytes in 0 blocks.
    ==5996== malloc/free: 2 allocs, 2 frees, 13 bytes allocated.
    ==5996== For counts of detected errors, rerun with: -v
    ==5996== No malloc'd blocks -- no leaks are possible.

    ------------------------------------------8<-----------------------------------------

    jaguarwan@Jaguar:~$ gcc -DCRASHME coincoin.c
    jaguarwan@Jaguar:~$ valgrind --tool=memcheck --leak-check=yes ./a.out
    ==6123== Memcheck, a memory error detector for x86-linux.
    ==6123== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
    ==6123== Using valgrind-2.2.0, a program supervision framework for x86-linux.
    ==6123== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
    ==6123== For more details, rerun with: -v
    ==6123==
    Supaire nom : plop
    data : 1337
    ==6123== Invalid read of size 1
    ==6123== at 0x1B902778: strlen (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x1B9648E4: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048649: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46060 is 0 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B902781: strlen (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x1B9648E4: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048649: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46061 is 1 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B985A01: _IO_file_xsputn@@GLIBC_2.1 (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B964874: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048649: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46063 is 3 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B9858F0: _IO_file_xsputn@@GLIBC_2.1 (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B964874: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048649: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46060 is 0 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    Supaire nom : plop
    data : 1337
    ==6123==
    ==6123== Invalid read of size 4
    ==6123== at 0x8048687: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46028 is 0 bytes inside a block of size 8 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x8048676: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B902778: strlen (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x1B9648E4: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048692: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46060 is 0 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B902781: strlen (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x1B9648E4: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048692: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46061 is 1 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B985A01: _IO_file_xsputn@@GLIBC_2.1 (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B964874: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048692: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46063 is 3 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    ==6123==
    ==6123== Invalid read of size 1
    ==6123== at 0x1B9858F0: _IO_file_xsputn@@GLIBC_2.1 (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B964874: _IO_vfprintf_internal (in /lib/libc-2.3.4.so)
    ==6123== by 0x1B96B0F1: _IO_printf (in /lib/libc-2.3.4.so)
    ==6123== by 0x8048692: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA46060 is 0 bytes inside a block of size 5 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x804862D: main (in /home/jaguarwan/a.out)
    Supaire nom : plop
    ==6123==
    ==6123== Invalid read of size 4
    ==6123== at 0x80486A3: main (in /home/jaguarwan/a.out)
    ==6123== Address 0x1BA4602C is 4 bytes inside a block of size 8 free'd
    ==6123== at 0x1B9033ED: free (in /usr/lib/valgrind/vgpreload_memcheck.so)
    ==6123== by 0x8048676: main (in /home/jaguarwan/a.out)
    data : 1337
    ==6123==
    ==6123== ERROR SUMMARY: 28 errors from 10 contexts (suppressed: 11 from 1)
    ==6123== malloc/free: in use at exit: 0 bytes in 0 blocks.
    ==6123== malloc/free: 2 allocs, 2 frees, 13 bytes allocated.
    ==6123== For counts of detected errors, rerun with: -v
    ==6123== No malloc'd blocks -- no leaks are possible.
  • # Ma très grande faute

    Posté par  (site web personnel) . Évalué à 3.

    Bon, j'ai trouvé d'ou ca venait. Et avec les infos que j'avais donnés ce n'était pas visible.
    Mon allocation de pGames est dans une fonction. du coup à la fin de celle-ci ... y' plus de tableau :(
    J'ai remplacé par pGames =(struct Game**) malloc (sizeof(struct Game*)*(catCountGames(filename)+1)); et ca marche beaucoup mieux.
    En tout cas, merci pour vos réponses et tests !

    (et dans la vrai vie, je vérifie mes allocations)
    • [^] # Re: Ma très grande faute

      Posté par  . Évalué à 1.

      Quand tu dis "dans la vrai vie", tu veux dire IRL ?? Tu parles donc des allocations familiales ?

      Oui, bon, ok, je sais ... -> []

      ;-]

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.