Free tableau de char* dans une structure [Résolu/Fermé]

Signaler
Messages postés
3
Date d'inscription
mardi 29 juillet 2014
Statut
Membre
Dernière intervention
30 juillet 2014
-
Messages postés
611
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
24 juin 2016
-
Bonjour,

je realise actuellement un shell (tres light), je cherche a free les elements de ma structure en sortie de boucle infinie apres un break

Je previens que je ne desire pas avoir de tableau statique, j'ai decide de n'utiliser que des pointeurs

Je cherche a free() un tableau de char*, alloue dynamiquement.
Je malloc() ma structure, dans un premier temps, dans mon main().



typedef struct s_shell
{
char *buffer;
char **env;
char **path;
} t_shell;

int main(void)
{
t_shell *sh;

if ((sh = (t_shell*)xmalloc(sizeof(*sh))) == NULL)
return (ERR);
while (42)
{ [...] }


Dans cette boucle j'appelle:

//premiere utilisation de la structure t_shell pour manip mon double tableau
if ((getenvt(sh)) == ERR)
return (ERR);



dans cette fonction, j'alloue le double tableau:

int getenvt(t_shell *sh)
{
int len;
int i;

i = 0;
len = -1;
sh->env = NULL;
while (environ[++len] != NULL);
if ((sh->env = xmalloc(len * sizeof(sh->env) + 8)) == NULL)
return (ERR);
while (i != len)
{
if ((sh->env[i] = xmalloc(strlen(environ[i]) * sizeof(**sh->env) + 1)) == NULL)
return (ERR);
sh->env[i] = environ[i];
i += 1;
}
sh->env[i] = NULL;
return (0);
}


Puis je recupere les inputs avec read, que je stocke dans un buffer, lui aussi present dans ma structure.

Si "quit" ou "exit" est tappe, je break dans le main() quittant ma boucle infinie.


J'aimerais donc a ce moment la, free tout mes pointeurs. Mais des que je cherche a free le double tableau, a l'execution, j'ai la sortie d'erreur suivante:

blabla@yep:~/test/env$ ./test
ex?> quit
bye..
*** Error in './test': free(): invalid pointer: 0x00007fff2db5f209 ***
Abandon (core dumped)
blabla@yep:~/test/env$


Voila le free:

[...]
free_elem(sh);
return (0);
}

void free_elem(t_shell *sh)
{
int i;

i = -1;
while (sh->env[++i] != NULL)
xfree(sh->env[i]);
i = -1;
while (sh->path[++i] != NULL)
xfree(sh->path[i]);
}



Je pense que je m'y prends mal et j'aimerais bien capter. Merci :)
Je tappe avec un clavier QWERTY, desole pour les accents^^

2 réponses

Messages postés
3
Date d'inscription
mardi 29 juillet 2014
Statut
Membre
Dernière intervention
30 juillet 2014

OK j'ai la reponse, je l'a publie pour ceux que ça interesseraient.


} // boucle inf.
for (i = 0; i != 8; i++)
free(sh->path[i]); //free de mon deuxieme tableau.
free(sh->env); //pas besoin de free chaque ligne, puisque je ne malloc() plus tout le tableau ligne/ligne
free(sh->path);
free(sh->buffer);
free(sh);
return (0);
} //fin du main



Aussi bete que cela, j'ai aussi vire le malloc de chaque ligne de mon tableau dans la fonction getenv

int get_all_env(t_shell *sh)
{
int len;
int i;

i = 0;
len = -1;
sh->env = NULL;
while (environ[++len] != NULL);
sh->envsize = len;
if ((sh->env = (char**)xmalloc(len * sizeof(*sh->env) + 8)) == NULL)
return (ERR);
while (i != len)
{
/* if ((sh->env[i] = (char*)xmalloc(strlen(environ[i]) * sizeof(**sh->env))) == NULL) */
/* return (ERR); */
sh->env[i] = environ[i];
i += 1;
}
sh->env[i] = NULL;
return (0);
}

avec valgrind et l'option --leak-check=full j'obtiens:

blabla@youpla:~/test/env$ valgrind --leak-check=full ./test
==14058== Memcheck, a memory error detector
==14058== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14058== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==14058== Command: ./test
==14058==
ex?> quit
bye..
==14058==
==14058== HEAP SUMMARY:
==14058== in use at exit: 0 bytes in 0 blocks
==14058== total heap usage: 12 allocs, 12 frees, 1,665 bytes allocated
==14058==
==14058== All heap blocks were freed -- no leaks are possible
==14058==
==14058== For counts of detected and suppressed errors, rerun with: -v
==14058== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Messages postés
611
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
24 juin 2016
37
Bonsoir
C'est bien de pouvoir corrigé son erreur ceci dit pour un programme comme un interpréteur de commande (simple), je ne vois pas pour le moment l'utilité d'une structure de données de plus les portions de ton code à savoir, la recherche du path système est très lourde sans compté que normalement elle a pour rôle de fournir le chemin (dans une variable passer en paramètre ) et non la fonction qui fournir un entier.

Le mécanisme d'incrémentation laisse un peu à désirer, s'il y a erreur ce traitement doit ce faire dans une autre fonction pas dans l'acquisition du patch, soit le chemin est vide soit pas de plus que les seuls cas où tu peux rien n'avoir comme Patch et argument est le cas ou l'interpréteur ne trouve pas de commande c'est-à-dire pas de binaire ou chemin vers ce binaire dans ce cas c'est une autre fonction qui est chargée de dire "commande inconnue",

Bref, tu fais compliqué alors que tu peux tout à fait faire simple.
et si tu comptes utiliser des structures, une union en plus dans la structure regrouperais tout ce qui est système et commande de la partie buffer mais (ce n'est qu'un avis). ou autre, ceci dit j'ai une question que viens faire
 xmalloc 
bref pour quoi utiliser l'en-tête
 #include <publib.h 
, de plus tu utilise pas les autre fonction comme
xfree

bref c'est pas portable ton code

à bientôt
Messages postés
3
Date d'inscription
mardi 29 juillet 2014
Statut
Membre
Dernière intervention
30 juillet 2014

xmalloc() et xfree() ne sont que des fonctions appellant respectivement malloc() et free() avec un perror() en plus.

Je me doute que l'utilisation et le parcours de double tableau n'est pas une situation optimale, à la base, je cherchais surtout à me comprendre les mécanismes d'allocation de mémoire sur des pointeurs, puis j'ai dérivé sur un Shell.
La manipulation (concaténation, découpage, copie,...) de chaînes de caractères n'est pas mon fort alors je m'entraîne, les contraintes je me les imposent comme d'éviter d'utiliser trop de fct systèmes ou bien les recoder.

--
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 675
Oui, c'est vrai que l'initialisation d'un canevas représente la majorité des cas ;-).

Un tableau de float/double pour une matrice?
Ce n'est pas portable...
Messages postés
4908
Date d'inscription
dimanche 12 juin 2011
Statut
Contributeur
Dernière intervention
3 février 2020
1 006
Ce n'est pas portable...
J'assumais l'utilisation de flottants IEEE754.
Messages postés
611
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
24 juin 2016
37
lol
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 675
Et je réitère : ce n'est pas portable...
Dis autrement : pas de calloc sur un type float...
Messages postés
611
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
24 juin 2016
37
Je m'en doutais que tu allais dira ça :) lol