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 asbin . Évalué à 2.
Si tu mets name dans une variable temporaire, ça peut contourner le problème, nan ?
autrement je vois pas ...
;-]
[^] # Re: bizarre
Posté par Mikaël Cordon . Évalué à 2.
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 Obsidian . Évalué à 3.
# La vérité est ailleurs
Posté par JaguarWan . Évalué à 3.
------------------------------------------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 jjl (site web personnel) . Évalué à 3.
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 asbin . Évalué à 1.
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.