Libération mémoire....

Résolu
Clonk Messages postés 278 Date d'inscription mardi 22 janvier 2002 Statut Membre Dernière intervention 29 août 2006 - 22 juil. 2004 à 15:18
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 - 23 juil. 2004 à 21:34
Bonjour,

Voilà, j'ai une appli qui utilise énormément de mémoire, jai plusieurs listes chainées de plusieurs milliers d'enregistrements, de nombreuses classes et pas mal de tableaux de char * (des char ** quoi).
C'est la première fois que je fais un projet de cette envergure en C++ et là, j'avoue que je ne capte pas :
J'utilise les delete autant que je peux, mais apparemment, lorsque je regarde l'utilisation mémoire pendant que ça mouline, ça ne me libère rien du tout! Et j'ai VRAIMENT besoin de libérer de la mémoire...
je vous donne un ou 2 exemples :

Ligne * freePtrligne(Ligne * Ptrligne)
{
Ligne * t = NULL;
while(Ptrligne != NULL)
{
t = Ptrligne;
Ptrligne = Ptrligne->suivant;
delete t->champ;
delete t;
}
return NULL;
}

pour vider une liste chainee de char *

ou bien quand je veux libérer un char **, je fais "delete[] mavar;"
Si quelqu'un sait pourquoi ça va pas...

Merci!

12 réponses

cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
23 juil. 2004 à 14:45
non non avec delete bien utilisé pas de memory leak.
si tu fais 'char ** donnees = new char * [256];'
c'est 'delete [] donnees;' qu'il faut faire. mais si entre temps t'as fais 'donnees[i] = new char[quelequechose];', (et c'est ce qui est fait dans ta fonction split); avant de faire 'delete [] donnees;', tu dois faire une boucle qui fait 'delete [] donnes[i];'

note que quand la taille est fixe (cad connue a la compilation), t'as pas besoin d'allouer de la memoire avec new, ex: dans ton split tu peux remplacer 'char * newname = (char *) malloc(64);' par 'char newname[64];' (et la pas besoin de libération).
tu dois allouer de la memoire qd la taille n'est pas connue a la compilation (ex elle dépend d'une variable comme size_t), ou bien quand ce qui est retourné par une fonction c'est un pointeur vers quelque chose (dans ce cas le pointeur qui est retourné doit pointer vers une zone mémoire allouée grace a new)

voila si ca a pu t'eclairer...
a+ ;)
3
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
22 juil. 2004 à 15:27
copie colle ici les endroits ou tu fais l'allocation (les new...).
a+ ;)
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
22 juil. 2004 à 15:33
autre truc, comment tu sais que ca va pas?
sous vc++, pour detecter les memory leaks :
#include <crtdbg.h>

et au début de ton main :

_CrtSetDbgFlag( _CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF );
_CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR);

la tu compiles ton programme, et tu fais Go (F5).

pour liberer avec delete, il faut que ton truc ait été alloué avec new et pas avec malloc ou quoi.
sinon t'as pas assez montré ton code pr k'je puisse t'en dire bcp plus...
a+ ;)
0
Clonk Messages postés 278 Date d'inscription mardi 22 janvier 2002 Statut Membre Dernière intervention 29 août 2006
22 juil. 2004 à 15:45
Bon, déjà, je vous montre pour l'allocation de la liste chainée dont je vous ai montré la libération:
Ltype * addnew(Type & t, Ltype * typ)
{
Ltype * tete = typ;
Ltype * nouveau = (Ltype *) malloc(sizeof(Ltype));
nouveau->typ = t;
nouveau->suivant = NULL;
if (typ == NULL)
typ = nouveau;
else
{
while (tete->suivant != NULL)
tete = tete->suivant;
tete->suivant = nouveau;
}
return typ;
}

effectivement, j'ai pas utilisé new, mais de mémoire, le new ne marche pas sur des structures définies dans le main().

Sinon, pour les char **, j'utilise uen fonciton split que j'ai développée, en gros, ça marche comme ça:
char ** donnees= NULL;
donnees	= split(ligne, limit, size_t);

et dans split :
char ** split(char * src, const char * car, int size_t = 0)	//Enlève les occurences de car dans src (renvoie t_result)
{
char ** t_result = NULL;
int i;
if (size_t == 0)
size_t= cpt_iteration(src, car);//cpt_iteration compte le nombre de car dans src
char * newname = (char *) malloc(64);
t_result = new char * [size_t];
for (i = 0; i<size_t; i++)
{
src = substr(src, car, newname);
t_result[i] = new char[64];
Trim(newname);
strncpy(t_result[i], newname, 64);
}
return t_result;
}


Voilà, j'espère que ça vous a éclairés sur mes erreurs...
Merci!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Clonk Messages postés 278 Date d'inscription mardi 22 janvier 2002 Statut Membre Dernière intervention 29 août 2006
22 juil. 2004 à 15:51
Oups! jme suis trompé dans la première fonction, C plutot ça:
Ligne * addligne(char * line, Ligne * Ptr)
{
Ligne * tete = Ptr;Ligne * nouveau (Ligne *) malloc(sizeof(Ligne));	nouveau->champ new char [512];
strncpy(nouveau->champ, line, 512);
nouveau->suivant = NULL;
if (Ptr == NULL)
Ptr = nouveau;
else
{
while (tete->suivant != NULL)
tete = tete->suivant;
tete->suivant = nouveau;
}
return Ptr;
}
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
22 juil. 2004 à 17:10
ben voila c'etait ca le probleme... delete et malloc sont incompatibles t'as de la chance que ca n'ait pas planté.
remplace tous tes malloc par des new.

"effectivement, j'ai pas utilisé new, mais de mémoire, le new ne marche pas sur des structures définies dans le main()."
si si ca marche !!

definis tes structures dans un .h, et inclus ce .h dans les .c ou .cpp ou tu fais des new et des delete, et tu verrras pas de prob.

Si une zone a été alloué par ex en faisant 'char* a = new char[64]', il faudra faire 'delete [] a;' et non pas 'delete a;'.
'delete a;' est a faire si la zone avait été allouée en faisant 'char* a = new char;'. jcrois ke tu savais ca, mais vérifie le a tous les endroit ou tu liberes, si t'as pas mis les [] qd il en fallait ou l'inverse, ca peut mener a un plantage, ou au mieux a une mauvaise liberation.

voila, a+ ;)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
22 juil. 2004 à 18:46
c'est pas etonnant que ton programme fuis de tout les cotés !
0
Clonk Messages postés 278 Date d'inscription mardi 22 janvier 2002 Statut Membre Dernière intervention 29 août 2006
23 juil. 2004 à 09:21
Bon, alors c'est presque ça...
mainteannt, je sias ce qui fuit, ce sont mes char **
mais ce que je capte pas, c'est que je fais les fameux delete[], mais il me les libère pas du tout... ou alors j'ai zappé quelque chose.
si je fais un :
char ** donnees = new char * [256];
alors quand je delete, je dois faire :
delete[] donnees;
ou:
delete[] * donnees;
ou autre chose???
j'ai essayé les 2, et apparemment ça me libère pas plus de mémoire que ça...
exemple dans mon code :
char ** donnees = NULL;
donnees	= split(ligne, limit, size_t);
/*Traitement...*/
delete[] * donnees;


nan???
Si j'ai fais une enorme erreur, merci de me le dire... j'avais jamais touché à la libération mémoire en C++ avant...
0
Stepharcher Messages postés 117 Date d'inscription samedi 12 avril 2003 Statut Membre Dernière intervention 8 septembre 2008
23 juil. 2004 à 13:03
Pour supprimer des données, je te conseil la fonction free

par exemple ton tableau "char** donnees" pour le supprimer de la mémoire tu fais :

for(i=0; i<a; i++)
free(donnees[i]);
free(donnees);

>:) Stéph >:)
0
Clonk Messages postés 278 Date d'inscription mardi 22 janvier 2002 Statut Membre Dernière intervention 29 août 2006
23 juil. 2004 à 14:11
merci stepharcher, mais ça donne la meme chose, la différence avec delete[]C qu'on n'a pas besoin d'avoir utilisé new pour libérer la mémoire.

Bon, par contre, juste pour vérifier, quand on a utilisé delete[], on a un memory leak de 1 byte à quand meme chaques fois ou pas?

Sinon je comprends pas pourquoi j'ai ça...
0
Clonk Messages postés 278 Date d'inscription mardi 22 janvier 2002 Statut Membre Dernière intervention 29 août 2006
23 juil. 2004 à 15:02
Aaaaah! ben ouais! là c'est beaucoup plus clair!!!
Je dis pas que ça va marcher du premier coup, mais là j'a capté le truc!
ça va m'éviter des casse-tête tout ça ;)
dernière question, un peu naive : char * donnees[128], ça me crée la meme chose que char ** donnees = new char * [128] sans avoir besoin de delete???
Merci :))
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
23 juil. 2004 à 21:34
'char * donnees[128];', est bien la meme chose que 'char ** donnees = new char * [128];', mais apres tu peux pas faire par exemple de 'return donnees;', a moins que donnees ne soit une variable globale. (en gros tu ne dois pas renvoyer dans une fonction un pointeur vers une variable qui est locale a ta fonction).
et effectivement qd tu fais char* donnees[128], pas besoin de libération (le tableau est alloué sur la base locale de ta procédure ou bien de la ou t'as ta derniere '{' , et est libéré automatiquement qd tu finis la procédure ou alors au moment ou tu sors de la ou t'étais en rencontrant un '}' ). dc qd tu connais la taille d'un tableau, et que celui ci ne sert que dans ta fonction ou procédure, ya que des inconvénients a utiliser new ou malloc a la place de ca.

a+ ;)
0
Rejoignez-nous