IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Désallocation d'un CHAR* retourné par une méthode


Sujet :

Langage C++

  1. #1
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut Désallocation d'un CHAR* retourné par une méthode
    Hello la communauté,

    je me pose une question sur une méthode que je viens de créer.
    la voici en très simplifiée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CHAR *CClasse::GetAddress(IN const BYTE *adresse, IN const BYTE size)
    {
    	CHAR *pc_retour;
    	pc_retour = new CHAR[size]; 
     
    	/* traitement ...
     
    	...*/
            return pc_retour;
    }
    Je crée donc un CHAR*, crée dynamiquement par new, pour retourner mon résultat, mais je ne peux pas désallouer moi-même ce CHAR*, ou alors, quand/comment le faire ?

    Merci d'avance pour vos réponses.

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Salut,

    je ne suis pas sure d'avoir saisie ton problème.

    Il faut que tu désaloues ton CHAR* une fois que tu ne t'en sers plus :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CClasse Classe;
    CHAR* Array = Classe.GetAddress(..., ...);
    // Traitement
    delete[] Array

    Essaye de préciser ton problème :-)

    NeoKript

  3. #3
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    je vais essayer d'être plus clair dans la méthode, je crée une chaine de caractères dynamiquement : pc_retour = new CHAR[size]
    Cette chaine est retournée par ma méthode : return pc_retour

    Donc, à chaque appel de ma méthode, la chaine est allouée par new, mais je ne peux la désallouer, car elle est retournée en résultat.

    Mon problème est que je ne sais pas quand désallouer cette chaine.
    Est-elle désallouer automatiquement après le return ?
    Si non, je dois le faire avec un delete, mais je ne vois pas où le placer...

    Est-ce que mon problème est plus compréhensible ?
    Si non, je réessaie...

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Citation Envoyé par niglo Voir le message
    Est-elle désallouer automatiquement après le return ?
    Non elle n'est pas désallouée automatiquement sinon tu ne pourrais pas te servir de ton CHAR* en dehors de ta méthode.
    Citation Envoyé par niglo Voir le message
    Si non, je dois le faire avec un delete, mais je ne vois pas où le placer...
    Comme dit dans mon précédent message, il faut que tu désalloue ton CHAR* lorsque tu n'a plus de traitement à faire sur cette variable :

    CClasse Classe;
    CHAR* Array = Classe.GetAddress(..., ...);
    // Traitement
    // Tu fais toutes les opérations que tu souhaites avec ton CHAR*
    // Tu le désaloues lorsque tu n'en a plus besoin
    delete[] Array;
    Essaye d'expliquer sur un exemple concret si ce n'est toujours pas ça.

  5. #5
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    Citation Envoyé par NeoKript Voir le message
    Salut,
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CClasse Classe;
    CHAR* Array = Classe.GetAddress(..., ...);
    // Traitement
    delete[] Array
    j'avais mal lu ton précédent mail

    Si j'ai bien compris, le CHAR*, utilisé et retourné par ma méthode (pc_retour), va être supprimé lors du delete de Array, qui reçoit le résultat de ma méthode.
    C'est bien ça ?

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Citation Envoyé par niglo Voir le message
    j'avais mal lu ton précédent mail

    Si j'ai bien compris, le CHAR*, utilisé et retourné par ma méthode (pc_retour), va être supprimé lors du delete de Array, qui reçoit le résultat de ma méthode.
    C'est bien ça ?
    Tout à fait, c'est lors de l'appel à delete[] que ton pointeur sera desaloué.

    Dans une application, il faut que tu ais autant de new que de delete pour pas qu'il y ai de fuite mémoire.

  7. #7
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    Citation Envoyé par NeoKript Voir le message
    Dans une application, il faut que tu ais autant de new que de delete pour pas qu'il y ai de fuite mémoire.
    OK, mais là, je n'aurai pas le même nombre, car le new dans ma méthode, n'aura toujours pas de delete .

    Si je l'utilise ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CHAR CharAddressFrom;
    CharAddressFrom = new CHAR[5];
    /*...*/
    CharAddressFrom= GetAddress(..., ...);
    /*...*/
    delete[] CharAddressFrom ;
    le CHAR* crée dans GetAddress n'aura pas son delete. Le delete "delete[] CharAddressFrom" détruit la variable CharAddressFrom et pas la variable pc_retour de ma méthode.
    Ou est-ce que le delete va détruire les 2 par "héritage" ?

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Citation Envoyé par niglo Voir le message
    OK, mais là, je n'aurai pas le même nombre, car le new dans ma méthode, n'aura toujours pas de delete .

    Si je l'utilise ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CHAR CharAddressFrom;
    CharAddressFrom = new CHAR[5];
    /*...*/
    CharAddressFrom= GetAddress(..., ...);
    /*...*/
    delete[] CharAddressFrom ;
    le CHAR* crée dans GetAddress n'aura pas son delete. Le delete "delete[] CharAddressFrom" détruit la variable CharAddressFrom et pas la variable pc_retour de ma méthode.
    Ou est-ce que le delete va détruire les 2 par "héritage" ?
    Je penses que tu n'as pas tout compris comment fonctionne les pointeurs ^^

    Je te fais un petit rappel à ma sauce rapidement, un pointeur en gros c'est l'adresse d'une variable (et non sa valeur !), c'est l'adresse à laquelle on va trouvé la valeur d'une variable dans la mémoire vive.

    Du coup, lorsque tu retourne un pointeur dans une méthode c'est une adresse qui est retournée et du coup c'est la même adresse qu'il y a dans
    pc_retour et Array.

    Le delete[] va donc détruire l'unique pointeur alloué !

    J'espère avoir été clair.

    NeoKript

  9. #9
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    merci pour ta réponse.
    C'est ce que j'avais compris, mais pas bien exprimé

    En tout cas, problème résolu, merci.

  10. #10
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      
     CHAR CharAddressFrom;
     CharAddressFrom = new CHAR[5];
     /*...*/
     CharAddressFrom= GetAddress(..., ...);
     /*...*/ 
      delete[] CharAddressFrom ;
    par contre dans ce code, à la ligne 5 tu as une fuite mémoire : tu perds l'unique référence sur ton allocation faite à la ligne 3. Il faut donc soit supprimer la ligne 3 si CharAddressFrom n'est pas utilisé avant la ligne 5 soit ajouter à la ligne 4 un "delete[] CharAddressFrom;"
    Et accessoirement, la première ligne devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CHAR * CharAddressFrom;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CHAR [] CharAddressFrom;

  11. #11
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    merci pour ce précieux conseil.

    J'ai modifié mon code en fonction de tes remarques pour ne pas avoir cette fuite de mémoire.

  12. #12
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Je pense que ta fonction ne devrait pas faire l'allocation, mais que l'appelant devrait allouer sa chaîne de caractères, la passer à ta fonction pour ensuite désallouer la chaîne. ça permettrait de respecter la notion de responsabilité de l'allocation / désallocation.
    Ca donnerait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // fonction GetAddress modifiée
    void CClasse::GetAddress(IN const BYTE *adresse, IN const BYTE size, BYTE * pRetour)
    { 
    	/* traitement ...
     
    	...*/
    }
     
    // Appel de GetAddress :
    CHAR CharAddressFrom;
     CharAddressFrom = new CHAR[5];
     /*...*/
    GetAddress(..., 5, CharAddressFrom);
     /*...*/ 
      delete[] CharAddressFrom ;
    Enfin, un e petite question, pourquoi n'utilises-tu pas std::string ?

  13. #13
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    je n'utilise pas String, car j'utilise un framework privé dans lequel les string n'existent pas

  14. #14
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Euh ... La STL est plutôt publique en fait. Elle est même implémentée partout, donc je ne vois toujours pas pourquoi tu ne l'utilises pas.

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si je devais bosser dans un environnement où les strings ne sont pas disponibles (ça existe, ça ?), la première chose que je ferais est de recréer une classe string à la main. C'est un investissement très vite rentabilisé.

  16. #16
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    je rouvre le sujet, car j'ai une autre question.

    Si j'utilise toujours la même méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CHAR *CClasse::GetAddress(IN const BYTE *adresse, IN const BYTE size)
    {
    	CHAR *pc_retour;
    	pc_retour = new CHAR[size]; 
     
    	/* traitement ...
     
    	...*/
            return pc_retour;
    }
    comment se passe la désallocation de ma variable "pc_retour" lors de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Adresse = %s", monObjet->GetAddress());
    Quelqu'un peut-il éclairer ma lanterne encore obscurcie ?

  17. #17
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Citation Envoyé par niglo Voir le message
    comment se passe la désallocation de ma variable "pc_retour" lors de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Adresse = %s", monObjet->GetAddress());
    Quelqu'un peut-il éclairer ma lanterne encore obscurcie ?
    Tu aura dans ce cas une fuite mémoire (pas de désallocation), afin d'éviter cela il faut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CHAR *address = monObjet->GetAddress();
    printf("Adresse = %s", address);
    delete[] address;
    Pour information, j'ai l'impression que tu mélange un peu c et c++.
    printf c'est du C, il serait préférable d'utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::cout << address << std::endl;

  18. #18
    Membre averti Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Points : 383
    Points
    383
    Par défaut
    merci pour ta réponse, c'est bien ce que je pensais, je vais faire les modifs en conséquence.

    mais non non, pas de mélange C/C++, j'ai juste repris le message déjà existant qui était du C++.

  19. #19
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    En général on déconseille ce genre de méthode qui renvoie un pointeur sur un espace mémoire alloué en laissant l'utilisateur de la méthode faire la desallocation. La première raison est que l'utilisateur peut oublier, la seconde est qu'il risque de mal le faire (utiliser un free plutôt qu'un delete, un delete plutôt qu'un delete[] etc.)

    Dans ton cas la méthode est dans une classe, ne peux-tu pas stocker ce pointeur dans la classe et le desallouer dans le destructeur de cette classe, si bien sur la durée de vie de la classe est adaptée...

  20. #20
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Citation Envoyé par niglo Voir le message
    merci pour ta réponse, c'est bien ce que je pensais, je vais faire les modifs en conséquence.

    mais non non, pas de mélange C/C++, j'ai juste repris le message déjà existant qui était du C++.
    Pas de quoi, par contre je persiste printf c'est du C et non du C++ ^^

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. objet retourné par une méthode
    Par wafiwafi dans le forum Général Java
    Réponses: 4
    Dernier message: 17/08/2011, 23h37
  2. Réponses: 9
    Dernier message: 20/06/2010, 20h30
  3. valeur retournée par une méthode
    Par soujava dans le forum Débuter avec Java
    Réponses: 5
    Dernier message: 02/05/2008, 21h20
  4. Type incompatible retourné par une méthode
    Par beegees dans le forum Langage
    Réponses: 4
    Dernier message: 22/04/2007, 19h23
  5. Réponses: 3
    Dernier message: 02/01/2007, 13h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo