Fuite de mémoire

Fermé
ben - 23 juil. 2009 à 11:46
 ben - 31 juil. 2009 à 12:30
Bonjour,

je suis débutant en c++.
je reprend le programme de quelqu'un.
mon problème est que ce programme contient des fuites de mémoire.
est-ce que quelqu'un pourrait m'aider.

mon programme contient plusieurs fonctions de ce style:

char *stringTochar_array(System::String ^s)
{
char* l = new char [s->Length];
int i=0;
while(i<s->Length)
{
l[i]=s[i];
i++;
}
l[i]='\0';
cout << "l stringtochar = " << l <<endl;
return l;
}

l'appel de cette fonction est:

char_string ch;
while (line != nullptr && strcmp(ch.stringTochar_array(line),rubrique)!=0)
{
line = sr->ReadLine();
}
line = sr->ReadLine();

(char_string est le nom de la classe qui contient la fonction "stringTochar_array", l'appel s'effectue à partir d'une autre classe)

le problème est que je return la variable que je dois désallouer.
est il possible de libérer la mémoire après le return?

Merci

10 réponses

Ben, bonjour

ATTENTION, il y a une première erreur dans la foncton stringTochar_array : il faut que l'allocation prévoie un caractère de plus que la longueur de la String :
char* l = new char [s->Length + 1];
C'est la place pour mettre le caractère \0 de fin de chaîne classique en C/C++ !

Sinon, La réponse à ta question est oui, si la classe string_ch ne se charge pas de faire de nettoyage de ce qu'elle a alloué. Par contre, il ne faut pas oublier que chaque appel de la méthode va retourner un tableau de char nouveau, il faut donc capturer le retour de la fonction dans une variable pointeur.

Je te conseille de transformer le code de l'appel de cette façon :
char_string ch;
char *adesallouer = null;
while (line != nullptr && strcmp(adesallouer=ch.stringTochar_array(line),rubrique)!=0)
{
line = sr->ReadLine();
// on desaloue si le pointeur vise une zone mémoire
if (adesallouer != null)
{
delete adesalouer;
// ne pas oublier de mettre à null pour le prochain appel.
adesalouer = null;
}
}
line = sr->ReadLine();
// Note comme ce code est un copier/coller de celui de dessus,
// je te conseillerai pour optimiser d'ajouter une méthode nettoyerCharString(char* t)
// a ta classe char_string et l'appeler dans les deux cas, ce sera plus propre.
if (adesallouer != null)
{
delete adesalouer;
// ne pas oublier de mettre à null pour le prochain appel.
adesalouer = null;
}
Bon courage, le C+ est plein de pièges concernant la mémoire !
3
Ok, Ben, c'est bien de trouver ses propres erreurs, et c'est peut-être là qu'on apprend le plus.

Attention, la fonction sprintf() n'alloue rien du tout :
C'est le développeur qui doit fournir un char[] suffisamment grand pour recevoir la chaîne formatée, toujours sans oublier de compter le \0 de fi de chaîne.
sprintf() fait la même chose que printf, sauf qu'elle écrit à partir du pointeur de char qu'on lui passe au lieu d'écrire dans la sortie standard (stdout)
Ne pas hésiter à mettre plus si on n'est pas sûr à l'octet près
Par exemple :

char monTexte[20];
sprintf(monTexte, "nombre = %d",200); // devrait rentrer avec n tableau de 13 seulement
Se méfier en particulier des affichage de nombre à virgule flottante.
Dans l'exemple donné, tu n'as rein à desallouer, pusique c'est un tableau à allocation automatique
Par contre, si j'avais fait :
char *pmonTexte= new char(20);
là, il faudra, lorsque j'en ai fini avec le pointeu pmontete, faire un delete(pmontexte);

De toute façon, pour les libération mémoire, tu comprendras facilement qu'une fonction ne peut pas savoir quand tu as fini de te servir de ton pointeur. Donc, sauf dans le cas de ce qu'on appelle les smart-pointer, ne compte pas sur les fonction classiques des librairies C/C++ pour faire le ménage dans la mémoire !

Ceci dit, moi je te conseillerait de jeter un coup d'oeil à la classe string qui fait partie des STL de C++.
Ce sont des classes qui justement manipulent des pointeurs intelligents, beaucoup plus agréables à utiliser
A condition que ton compilateurles fournisse


bon courage !
2
Bonjour,

Ok, merci à toi, je regarde ça.

j'ai tout de même une question.
mon programme tourne dans une boucle infinie. il lance des threads à différentes heures qui sont inscrites dans un fichier "thread.ini". mon programme compare donc toutes les secondes l'heures du système et les heures contenues dans "thread.ini". puis quand les heures correspondent il lance un thread.
il me semble que j'ai désalloué tous les pointeurs.
seulement toutes les secondes, mon programme utilise 4K de mémoire en plus.

d'ou ma question: est-il inévitable qu'il y ait cette augmentation?
ou cela signifie que je n'ai pas tout désalloué?
lorsque le programme tourne, si tout est bien désalloué, la mémoire reste stable?
0
Bonjour,

J'ai encore quelques fuites de mémoire.
J'ai trouvé le moyen de les localiser
Comment faire pour libérer la mémoire après return ?

Je m'explique
Par exemple j'ai un fonction

char *array(System::String ^s)
{
_CrtDumpMemoryLeaks();
char* l = new char [500];
int i=0;
while(i<s->Length)
{
l[i]=s[i];
i++;
}
l[i]='\0';
return l;
}

Je ne comprends pas comment faire en sorte que le programme sache que la mémoire qu'il faut désallouer se trouve dans cette fonction.
Quand une fonction return" 0" ou "1", on peut effectuer le "delete" dans cette fonction.
Seulement quand on fait le delete hors de la fonction, comment lui spécifié qu'il doit deleter la mémoire allouée dans cette fonction.

désolé pour mes explications un peu brouillon!!

Merci d'avance
1
bonjour,

je te remercie java4ever pour ta réponse.
seulement j'ai un autre souci.

l'appel à ma fonction "stringTochar_array" s'effecute à partir d'une autre fonction qui retourne aussi une valeur(qui est dépendante de la valeur renvoyée par "stringTochar_array")
quand je lance mon programme j'ai une boite de dialogue ou je doit faire "abort"

voici l'appel en entier:

class donnee_ini
{
public :
char *donnee(char* rubrique, char *sousRubrique )
{
char* l = new char [500];
System::String ^line;
System::IO::StreamReader ^sr=gcnew StreamReader("thread.ini");
line = sr->ReadLine();
char_string ch;
while (line != nullptr && strcmp(ch.stringTochar_array(line),rubrique)!=0)
{
line = sr->ReadLine();
}
line = sr->ReadLine();
while (line != nullptr && strcmp(ch.prefixe(ch.stringTochar_array(line),'='),sousRubrique)!=0)
{
line = sr->ReadLine();
}
l= ch.sufixe(ch.stringTochar_array(line),'=');
cout << "l = " << l <<endl;
return l;
}
};

si tu as besoin de plus de précision sur mon programme, je peux t'en donner.

Merci
0

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

Posez votre question
ben, je vois bien que tu es dans la panade, mais là tu demande de faire le travail à ta place, ce qui à mon avis n'est pas le but du forum.
J'ai l'impression que cette appli est mal écrite, et qu'il faudrait faire une revu complète du code.
Je fais régulièrement ça dans mon travail, mais c'est un travail trop long pour être juste un coup de main.
Désolé de ne pouvoir t'aider davantage, , mis peut-être quelqu'un d'autre le fera ?
0
salut java4ever,

en fait après avoir posté mon dernier message je me suis rendu compte que j'avias fais une erreur.

les conseils que tu m'as données m'ont été trés utiles.
j'ai encore des fuites mais sur d'autres fonctions du même type, je pense que je devrais m'en sortir

un grand merci à toi.
0
bonjour, j'ai quand même une autre question svp,

l'instruction "sprintf" libère la mémoire qu'elle à allouer à la fin de la fonction?

merci
0
Bonjour, ben.
La réponse est en quelque sorte dans la question : si tout est dé-s-alloué, il ne doit pas y avoir augmentation de la mémoire !
Il existe des logiciels (pas très nombreux qui permettent de détecter les fuites mémoires (memory leak en anglais)
Malheureusement, il n'y en a pas beaucoup de gratuits, et ceux qui ne le sont pas sont chers, comme par exemple BoundsChecker de Numega. Il y a aussi IBM Rational Purify qui a eu son heure de gloire, mais qui ne fait pas l'unanimité.
si tu es sous linux, tu peux chercher valgring (http://www.valgrind.org) qui est gratuit (GNU)
Sous Windows, j'ai trouvé ce lien, mais je ne l'ai pas utilisé : à tester.

Avant toute chose, il faut que tu passe au crible toutes les allocations mémoire que tu peut détecter, et voir si elle ont dé-s-allouées.
Regarde notamment du côté des thread eux même que sont peut être des objets mis dans une liste ?
Est-ce que les thread ne tournent pas indéfiniment ?
Sinon, sans utiliser un logiciel, tu peut faire des recherches sur les gestionnaires de mémoire, en particulier en suivant le tutorial (excellent) ci-dessous :
https://loulou.developpez.com/tutoriels/moteur3d/partie1/

Il se peut aussi que les fuites mémoires viennent d'une librairie tierce (ou maison faite par un informaticien partit depuis belle lurette), à vérifier aussi.

Bon courage !
0
goldenmike Messages postés 315 Date d'inscription samedi 21 juillet 2007 Statut Membre Dernière intervention 23 août 2012 52
27 juil. 2009 à 12:46
+ 1
cmoivoilou xD
0
cmoivalou Messages postés 491 Date d'inscription mercredi 5 décembre 2007 Statut Membre Dernière intervention 22 décembre 2013 53
27 juil. 2009 à 18:01
Merci merci :)
0