Tableau de liste

Signaler
Messages postés
8
Date d'inscription
lundi 31 mars 2008
Statut
Membre
Dernière intervention
3 juillet 2008
-
Messages postés
2
Date d'inscription
mercredi 6 juillet 2005
Statut
Membre
Dernière intervention
13 septembre 2009
-
Bonjour,
J'ai un programme en C avec une liste chainee simple dont voici la declaration :
typedef struct Element_
{
    int map;
    char val[4];
    struct Element_ * suivant;
}Element;


Pour les besoins de mon application, je cree ensuite un tableau de liste.
Element * tab = (Element*)malloc(sizeof(Element)*76);

Le tableau est initialisé avec tous les map à  0, val à  "" et suivant à  NULL. Ensuite je remplis le tableau. Par exemple je peux avoir quelque chose du genre:

Case 0: val="abc\0" map=1 , suivant=NULL
.....
...
case 76: val="etc\0" map=5, suivant:val="epu\0" map=1, suivant=NULL

Mon programme fonctionne correctement et fait bien ce que je veux. Mais je rencontre un probleme lorsque je vais liberer l'espace alloué pour le tableau de liste. J'ai pensé à  faire une fonction qui permet de liberer une case et ensuite faire une boucle pour liberer toutes les autres.

int liberer(Element* p)
{
    Element *tmp;
    while(p)
    {
    tmp=p->suivant;
    free(p);
    p=tmp;
    }
    return 0;
}
Vu que je veux faire une modification, je passe en parametre un pointeur sur la case et j'appelle la fonction avec l'adresse de la case. Par exemple : liberer(&tab[0]);
Jusque là  tout va bien (enfin pour la premiere case), mais dès que je veux passer à  la case suivante, j'ai un SIGSEGV. J'ai regardé dans le debogueur et j'ai cette information : ***glibc detected *** /home/seb/appli/debug/src/appli: free(): invalid pointer: 0x0805e5e4 (c'est l'adresse de la case 1 apres avoir liberé la case 0).

Quelqu'un aurait-il une solution à  mon problème?
Merci

3 réponses

Messages postés
5
Date d'inscription
samedi 12 janvier 2008
Statut
Membre
Dernière intervention
18 mai 2008

Salut,

euh si c'est juste libérer la place allouer à ce moment là: "Element * tab = (Element*)malloc(sizeof(Element)*76);" avec malloc, il suffit d'utiliser free.
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

Bonjour,

1) "Pour les besoins de mon application, je cree ensuite un tableau de liste."
Non, c'est juste un tableau de structures et non une liste ou un tableau de listes. Le champ suivant n'a aucune utilité du coup, d'ailleurs il est systématiquement mis à NULL dans le switch d'initialisation. A moins d'imaginer que, par la suite, les éléments du tableau se pointent les uns les autres, comme après un tri !

2) "J'ai pensé à  faire une fonction qui permet de liberer une case et ensuite faire une boucle pour liberer toutes les autres."
Pourquoi ? Les éléments de la liste n'ont pas été alloués, il n'y a donc pas de raison de les désallouer ! Quand la liste est créée, chaque élément occupe déjà sa pleine propre place : 1 entier + 4 caractères + 1 pointeur. Celà ne serait pas le cas (et il faudrait effectivement une boucle de désallocation) si val était un pointeur sur une chaîne de caractères allouée au moment de son initialisation. Une simple libération du tableau suffit.

3) Case 0: val="abc\0" map=1 , suivant=NULL ne va pas du tout !
c'est plutôt : case 0 : strcpy(val,"abc"); map=1; suivant=NULL; break;

Jean-François
Messages postés
2
Date d'inscription
mercredi 6 juillet 2005
Statut
Membre
Dernière intervention
13 septembre 2009

En résumé ce que jfrancois veut te dire c'est que le tu ne peux pas désallouer une case de ton tableau parce que tu as allouer tes 76 éléments d'un coup.

En gros le principe du free c'est une désallocation par malloc :

Tu fais un malloc, tu devras faire un free;
deux malloc, deux free...

Ton code devrait donc être dans ce style la alors pour l'allocation de mémoire et faire une vrai chaine liée,
mais l'inconvénient, c'est que tu ne pourra plus acceder par indice à tes éléments.

Element * tab = NULL;
Element* tmp = NULL;
//premier élément alloué
tab = (Element*)malloc(sizeof(Element));
tmp = tab;
for(int i = 0; i < 74; i++){
   tmp->suivant = (Element*)malloc(sizeof(Element));
   if(!tmp)
      error;
   tmp = tmp->suivant;
}
//dernier élément
   tmp->suivant = (Element*)malloc(sizeof(Element));
   if(!tmp)
      error;
   tmp->suivant = NULL;