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

 C Discussion :

utilisation du free sur un char*


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut utilisation du free sur un char*
    Bonjour,

    Dans une fonction, j'ai declare une variable char* :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* Separateurs = " ,;\t"
    A la fin de ma fonction, j'ai fait :
    Sans qu'il y est de plantage, j'avais des soucis lors du debuggage : le compilo faisait comme si il y avait plusieurs breakpoints invisibles dans l'instruction free.

    J'ai enleve le free et plus aucun probleme.

    Pouvez vous me confirmer la non utilite du free et m'en expliquer la raison ?
    Merci d'avance pour votre aide.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Dans l'exemple que tu fournies, Separateur est un pointeur sur une chaine de caractères qui est en mémoire.

    Tu n'as absolument pas besoin de la libérer, c'est même une erreur que de faire un free() dessus, le fait qu'il n'y ait pas eu plantage est un hasard.

    Donc non, pas de free() dessus
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Ton pointeur Separateurs pointe vers un tableau de caractère statique créé par le compilateur. Il ne faut pas le libérer.

    D'un point de vu mémoire, est équivalent à .

    Le free ne s'appelle que pour les allocations faites à l'aide de malloc, calloc, realloc et strdup.

  4. #4
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut
    OK merci beaucoup pour vos lumières.
    Encore une petite precision, j'ai dans le meme temps declare des variables qui elles sont initialisees avec une copie par exemple avec strdup ou strtok

    Voici le code complet de ma fonction, est ce que vous y voyez une erreur ?
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    /** @brief The function search and scan all DATAS block into the NODES block.
    *
    * @param NodesElem is the element in the XML witch is the begin of the NODES block.
    *
    * First it retrieves a header which give destination variables and then it retrieves the datas stocked in table format.
    **/
    void CStudySytem::LoadXML_TabNodesValues( TiXmlElement *NodesElem)
    {
        TiXmlElement *DatasElem,*HeaderElem,*ValuesElem;
        char *HeaderString=NULL, *HeaderWord=NULL, *ValuesString=NULL, *ValueWord=NULL, *Separators = " ,;\t";
     
        DatasElem = NodesElem->FirstChildElement(XML_DatasTable);
        while ( DatasElem)
        { // Here I'm in a DATAS block
            // I search the first Header element :
            HeaderElem=DatasElem->FirstChildElement(XML_DatasHeader);
            // and the first block Values element :
            ValuesElem=DatasElem->FirstChildElement(XML_DatasValues);
            if (!HeaderElem or !ValuesElem)
            {   // No header or no Values! I leave this DATAS block and continue
                DatasElem=DatasElem->NextSiblingElement(XML_DatasTable); // I loop on all possible datas block
                continue; // go to the next DATAS block
            }
            // I stock each header element seperatly in a list
            HeaderString = strdup(HeaderElem->GetText());
            list<string> Header;
            HeaderWord = strtok (HeaderString,Separators); // scan with space, coma, semicolon and tab caracter
            while (HeaderWord)
            {
                Header.push_back( HeaderWord);
                HeaderWord = strtok (NULL,Separators);
            }
     
            if( Header.empty())
            {   // No header : I leave this DATAS block and continue
                DatasElem=DatasElem->NextSiblingElement(XML_DatasTable); // I loop on all possible datas block
                continue; // go to the next DATAS block
            }
     
            ValuesString = strdup(ValuesElem->GetText());
            ValueWord = strtok (ValuesString,Separators); // scan with space, coma, semicolon and tab caracter
            list<string>::iterator iHeader = Header.begin(); // I place a pointer on the first header
     
            TIndex Index = 0;
            TNumeric X=0.0f,Y=0.0f,Z=0.0f;
            while ( ValueWord)
            {
     
    //            cout<<*iHeader<<" = "<<ValueWord<<endl;
     
                if      ( strcmp((*iHeader).c_str(),XML_NodeIndex.c_str()) == 0 )
                    Index = strtol(ValueWord,NULL,10);
                else if ( strcmp((*iHeader).c_str(),XML_NodeXCoord.c_str()) == 0 )
                    X = strtof(ValueWord,NULL);
                else if ( strcmp((*iHeader).c_str(),XML_NodeYCoord.c_str()) == 0 )
                    Y = strtof(ValueWord,NULL);
                else if ( strcmp((*iHeader).c_str(),XML_NodeZCoord.c_str()) == 0 )
                    Z = strtof(ValueWord,NULL);
    //            else // Error, header unknown !
     
                // treat the next value :
                ValueWord = strtok (NULL,Separators);
                ++iHeader;
                if ( iHeader == Header.end())
                {
                    // I create the new node with his properties :
                    TIteratorOnANode iNewNode = AddANode(Index);
                    if (iNewNode!=NULL)
                        iNewNode->SetPositionInSpace(X,Y,Z);
                    // Next value will be for the first header, with blank properties :
                    Index = 0;
                    X=0.0f;
                    Y=0.0f;
                    Z=0.0f;
                    iHeader = Header.begin();
                }
            }
     
            DatasElem=DatasElem->NextSiblingElement(XML_DatasTable); // I loop on all possible datas block
        }
     
        free(HeaderString);
        free(HeaderWord);
        free(ValuesString);
        free(ValueWord);
    //    free(Separators);
    }
    Encore merci.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    C'est du C++, ça...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Seules HeaderString et ValuesString doivent être libérées avec free(), car seules ces deux chaînes sont allouées avec malloc() ou strdup().
    strtok() retourne un pointeur vers la chaîne elle-même, donc pas besoin de free() dessus.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En déclarant ainsi tes variables, tu peux mieux voir ce qui doit être détruit ou non:
    Code C/C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *HeaderString=NULL, *ValuesString=NULL;
    char const *HeaderWord=NULL;
    char const *ValueWord=NULL;
    char const * const Separators = " ,;\t";
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    j'ai dans le meme temps declare des variables qui elles sont initialisees avec une copie par exemple avec strdup ou strtok
    strdup crée une nouvelle chaîne par allocation dynamique et copie la chaîne en argument. Par conséquent, il y a lieu de faire un free sur le pointeur renvoyé par strdup pour récupérer la mémoire.

    Par contre, strtok ne crée pas une chaîne ni ne l'initialise. Il modifie la chaîne passée en argument lors du premier appel. Par conséquent, il ne faut pas faire de free sur les pointeurs renvoyés par cette fonction (ValueWord et HeaderWord).
    Dans ton cas, il me semble que lorsqu'on arrive à free(ValueWord ) et free(HeaderWord), ValueWord et HeaderWord sont à NULL, ce qui te sauve et fait que ça ne plante pas. Néammoins, ces deux free sont inutiles et illogiques.

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kase74 Voir le message
    OK merci beaucoup pour vos lumières.
    Encore une petite precision, j'ai dans le meme temps declare des variables qui elles sont initialisees avec une copie par exemple avec strdup ou strtok
    strdup() (fonction POSIX.1, mais non standard C, je le rappelle) fait une copie dynamique avec malloc(), mais strtok() ne fait aucune copie. Elle se contente de découper la chaire originale et de retourner l'adresse du début de chaque sous chaine...

    Il ne faut pas coder au hasard. Il faut lire la doc des fonctions pour savoir ce qu'on fait et ce qu'il faut faire...

    Une bonne référence :

    http://www.opengroup.org/onlinepubs/...ns/strdup.html
    http://www.opengroup.org/onlinepubs/...ns/strtok.html

    Voici le code complet de ma fonction, est ce que vous y voyez une erreur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /** @brief The function search and scan all DATAS block into the NODES block.
    *
    * @param NodesElem is the element in the XML witch is the begin of the NODES block.
    *
    * First it retrieves a header which give destination variables and then it retrieves the datas stocked in table format.
    **/
    void CStudySytem::LoadXML_TabNodesValues( TiXmlElement *NodesElem)
    Pas du C.

  10. #10
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut
    Merci pour vos reponses.
    Je prends bien note du site reference que je vais mettre en haut de ma liste.

  11. #11
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par mabu Voir le message
    D'un point de vu mémoire, est équivalent à .
    Non. La premiere forme alloue un tableau de 5 caracteres pouvant etre modifie. La deuxieme alloue un pointeur, pouvant etre modifie, qui est initialise a l'adresse d'un tableau de 5 caracteres ne pouvant pas etre modifie (meme si il ne faut pas que toto soit const pour que ce code passe en C).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de free() sur un char **
    Par Webby1234 dans le forum C
    Réponses: 11
    Dernier message: 11/06/2010, 09h51
  2. Réponses: 16
    Dernier message: 12/11/2008, 20h36
  3. Réponses: 6
    Dernier message: 11/11/2008, 17h26
  4. quel language utiliser pour agir sur un log automatiquent
    Par qegukom dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 05/08/2004, 21h00
  5. free sur des tableaux "a moitié dynamiques"
    Par barthelv dans le forum C
    Réponses: 4
    Dernier message: 31/07/2003, 15h30

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