Liberation de memoire

Signaler
Messages postés
4
Date d'inscription
jeudi 23 juillet 2009
Statut
Membre
Dernière intervention
4 août 2009
-
Messages postés
112
Date d'inscription
lundi 29 juin 2009
Statut
Membre
Dernière intervention
5 novembre 2009
-
bonjour,

je suis debutant en c++.
j'ai un petit souci de liberation de memoire.

je voudrai savoir comment peut-on desallouer "new" qui est dans une fonction qui return une valeur.

Par exemple:
char *mafonction(char *s,char c)
{
int i=0;

char* l = new char [15];
while(s[i]!=c && (unsigned int)i<strlen(s))
{
l[i]=s[i];
i++;
}
l[i]='\0';

return l;
}

est ce que je peux faire un "delete l;" après le "return l;"?

9 réponses

Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Bonjour,

Non, tu ne peux rien faire après return.

Par contre tu peux faire

char *l = mafonction(s,c);
delete []l;
Messages postés
3983
Date d'inscription
jeudi 14 juillet 2005
Statut
Membre
Dernière intervention
30 juin 2013
13
Exact. Surtout fais attention à faire delete[] et pas delete tout seul. Sinon il ne va libérer qu'un octet.

---
VB.NET is good ... VB6 is better
Messages postés
4
Date d'inscription
jeudi 23 juillet 2009
Statut
Membre
Dernière intervention
4 août 2009

bonjour,

merci à vous.
j'ai essayé avec votre méthodes mais rien n'y fait.
je n'ai toujours pas réussi à libérer ma mémoire.
ça fait deux semaines que je suis dessus , j'ai tout essayé mais je ne trouve pas !!!
est ce que quelqu'un veut bien m'aider SVP?
Messages postés
112
Date d'inscription
lundi 29 juin 2009
Statut
Membre
Dernière intervention
5 novembre 2009

Un peu de méthodologie : repense déjà à ce que tu veux faire.
Si j'ai bien compris ton problème, tu as besoin de couper une chaine à un caractère donné.

Quelques remarques : new char[15] ... NON ! (sauf si tu peux garantir à 100% que on ne dépasse pas les 14 caracteres)
Tu ne peux pas prédire la taille de string de s.Pense également que strlen est faite pour compter le nombre de caractères avant le premier \0 dans ta string.



Fait très attention à la désignation de ta fonction. Ici, je vois "(char *s,...)" ce qui pourrais sous-entendre que ta fonction modifie le contenu de la chaine s.

Pourquoi cette nuance ?
En C / C++, il faut toujours savoir dans quoi on travaille.

Je te propose un autre algorithme qui coupe une chaine lorsque le caractere x est trouvé, et renvoit la position du caractere suivant à x:


/**
Fonction qui coupe une chaine bonjourXbonsoir en deux strings : bonjour bonsoir et qui renvoit la position de bonsoir.
Comportement indéfini pour x==0
**/
char * cutAndGo(char * src, char x){
while(src[0]){
if(src[0]==x){
src[0]=0;
return src+1;
}
}
return NULL;
}


exemple d'appel:
char * s="salut bob"
char x=' '
char * s2=null
** APPEL DE s2=cutAndGo(s,x)**
s="salut"
x=' '
s2="bob"


Pour en revenir à la gestion de mémoire, tu dois faire un delete APRES avoir apellé ta fonction comme ed73 l'a indiqué.
Tu dis avoir tout essayé ,que t'as donné cette tentative ?



; I'm just keeping the hopeless cross to increase the meaninglessness
Messages postés
112
Date d'inscription
lundi 29 juin 2009
Statut
Membre
Dernière intervention
5 novembre 2009

J'ai oublié un src++ à la fin de ma boucle :'(

; I'm just keeping the hopeless cross to increase the meaninglessness
Messages postés
4
Date d'inscription
jeudi 23 juillet 2009
Statut
Membre
Dernière intervention
4 août 2009

bonjour Kotomine,

désolé j'ai eu des soucis de connexion.

mon programme tourne dans une boucle infinie.
il lance des threads à des heures indiquées dans un fichier "thread.ini"
qui se trouve dans le même repertoire que mon application.

mon programme compare donc toutes les secondes l'heures du système et les heures
qui se trouvent dans "thread.ini".

seulement, la fonction que j'ai indiquée plus haut est appellée dans une autre fonction du même type. (donc qui return une valeur)

si cela t'interesse je peux te montrer mon programme.
j'ai essayé ce que m'a proposé ed73 sans succés, j'ai toujours une fuite de memoire.
je n'ai plus d'idée. je suis dessus depuis 2 semaines.
un oeil nouveau et plus expert serait le bienvenue.

merci
Messages postés
4
Date d'inscription
jeudi 23 juillet 2009
Statut
Membre
Dernière intervention
4 août 2009

si quelqu'un veut bien m'aider.

j'ai ces 3 fonctions dans la classe "char_string"
	                    /*************************************************
                            *                  stringTochar_array            *
                            *************************************************/ 
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';
return l;
}

    /*************************************************
                            *               prefixe                          *
                            *************************************************/ 
char *prefixe(char *s,char c)
    {   
int i=0;           
char* l = new char [500];
        while(s[i]!=c && (unsigned int)i<strlen(s))
        {
            l[i]=s[i];
            i++;
        }
l[i]='\0';
return l;
}

    /*************************************************
                            *                     sufixe                     *
                            *************************************************/ 
char *sufixe(char *s,char c)
    {   
int i=0,j=0;
        char* l = new char [500];
        while(s[i]!=c)
        {
            i++;
        }
        i++;
        while((unsigned int)i<strlen(s))
        {
            l[j]=s[i];
            j++;
            i++;    
} 
l[j]='\0';
        return l;
    }


je fais appel à ces fonctions à partir d'une fonction qui est dans une autre classe "donnee_ini"
	char *donnee(char* rubrique, char *sousRubrique )
{
char* l 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),'=');
return l;
}


enfin, je fais appel à cette fonction dans mon "main" de cette manière:
while(ch.compare_heure(date_time,ini.donnee("[thread-time]","time1"))==-1)				//si l'heure correspond à celle du fichier thread.ini (time1), lancement du thread1)   
{
date_jour=gd.date_heure_jour();   
sprintf(date_time,"%d:%d:%d",date_jour.Hour,date_jour.Minute,date_jour.Second);
}
thread1^ Object1 = gcnew thread1();
Thread^ InstanceCaller1 = gcnew Thread(gcnew ThreadStart(Object1, &thread1::premier_thread));
InstanceCaller1->Start();			// lancer Thread1
i++;
InstanceCaller1->Join();		// le Thread2 ne se lance que quand le Thread1 est fini


j'ai essayé différentes méthodes pour désallouer la mémoire, mais pas encore la bonne!!

merci d'avance
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Bonjour,

Dans ta fonction donnee(...) tu écris char *l new char[500] puis plus bas l ch.suffixe(...) qui alloue également 500 caractères.

En faisant cela, tu perds la référence à la zone mémoire allouée au début de ta fonction donnee(...) et tu ne pourras plus la libérer toi-même.
Messages postés
112
Date d'inscription
lundi 29 juin 2009
Statut
Membre
Dernière intervention
5 novembre 2009

Une fuite mémoire peut être résolue de 2 façons:
* Tout étudier, passer dans valgrind, etc..
* Rendre la fuite négligeable

je vais opter pour la seconde façon.

Si je ne me trompe pas, tu analyse ton fichier .ini périodiquement. Il peut changer au cours du temps ou non ? Si c'est pas le cas, analyse une seule fois ton fichier dans des tables !


Je reviens sur la première façon d'agir (la gestion pointue) , vu que je viens de trouver d'où ça vient :
Tu utilises
if (strcmp(prefix, ...)){
}

La ouais, la mémoire est perdue.
Tu devrais faire
char * tmp=prefix();
if(strcmp(tmp, ...)){


}
delete [] tmp;

(mais là encore, pense que tu alloues 500 octets juste pour comparer des chaines.
je te conseillerais de faire une fonction

// fonction qui compare une chaine b pour 
// verifier si elle commence par le prefixe
bool prefixEquals(const char * prefix, const char *b,char sep){
for(int i=0; prefix[i] != 0 && prefix[i] != 0;i++){
if(prefix[i]==sep && b[i]==sep){
return true;
}
}

return false;
}




; I'm just keeping the hopeless cross to increase the meaninglessness