Liberation de memoire

bobaben Messages postés 4 Date d'inscription jeudi 23 juillet 2009 Statut Membre Dernière intervention 4 août 2009 - 31 juil. 2009 à 17:06
Kotomine Messages postés 112 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 5 novembre 2009 - 4 août 2009 à 10:15
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

ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
31 juil. 2009 à 17:50
Bonjour,

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

Par contre tu peux faire

char *l = mafonction(s,c);
delete []l;
0
cs_ghuysmans99 Messages postés 3982 Date d'inscription jeudi 14 juillet 2005 Statut Membre Dernière intervention 30 juin 2013 16
31 juil. 2009 à 18:50
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
0
bobaben Messages postés 4 Date d'inscription jeudi 23 juillet 2009 Statut Membre Dernière intervention 4 août 2009
3 août 2009 à 12:19
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?
0
Kotomine Messages postés 112 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 5 novembre 2009
3 août 2009 à 13:50
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
0

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

Posez votre question
Kotomine Messages postés 112 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 5 novembre 2009
3 août 2009 à 13:51
J'ai oublié un src++ à la fin de ma boucle :'(

; I'm just keeping the hopeless cross to increase the meaninglessness
0
bobaben Messages postés 4 Date d'inscription jeudi 23 juillet 2009 Statut Membre Dernière intervention 4 août 2009
3 août 2009 à 14:49
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
0
bobaben Messages postés 4 Date d'inscription jeudi 23 juillet 2009 Statut Membre Dernière intervention 4 août 2009
4 août 2009 à 10:00
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
0
ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
4 août 2009 à 10:11
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.
0
Kotomine Messages postés 112 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 5 novembre 2009
4 août 2009 à 10:15
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
0
Rejoignez-nous