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 :

Changement contenu variable non desiré


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Par défaut Changement contenu variable non desiré
    Bonjour à tous,

    j'ai un probleme avec mon code et je ne sais pas d'ou ca vient.

    Voila j'ai une classe qui a une fonction créerfichier() qui crée un fichier XLM et une fonction GetNom() qui renvoie le nom du fichier créer dans un char* de ma classe. ma Classe est situé dans une DLL (je pense pas que ca change grand chose mais bon).

    Dans mon programme j'ai une fenetre avec un bouton qui appelle a la suite :
    - la fonction créerfichier()
    - une fonction d'une autre classe qui me permet d'aller recuperer des informations dans un gros documents texte.
    - et une autre fonction qui permet d'ecrire les infos trouver dans le fichier créer.

    cette deuxieme fonction a besoin du nom du fichier je fais donc appel a GetNom() mais quand je fais GetNom() juste apres creerfichier() je recupere le on nom. Par contre quand il y a une focntion entre créerfichier() et GetNom() commme dans mon cas la fonction qui recupere les infos. Et bien la varaible qui contient le nom du fichier et modifié... alors que rien dans la fonction ne le demande et ne touche à cette variable ! La valeur est enfaite remplacer par un bout de texte du fichier dont je recupere les infos...

    Du coup je pense que ca doit venir de la memoire mais j'aimerais bien comprendre le comment du pourquoi de la chose .

    Voila j'espere que j'ai été clair et que vous pourrez m'aider.

  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
    Citation Envoyé par adurandet Voir le message
    Bonjour à tous,

    j'ai un probleme avec mon code et je ne sais pas d'ou ca vient.

    Voila j'ai une classe qui a une fonction créerfichier() qui crée un fichier XLM et une fonction GetNom() qui renvoie le nom du fichier créer dans un char* de ma classe. ma Classe est situé dans une DLL (je pense pas que ca change grand chose mais bon).

    Dans mon programme j'ai une fenetre avec un bouton qui appelle a la suite :
    - la fonction créerfichier()
    - une fonction d'une autre classe qui me permet d'aller recuperer des informations dans un gros documents texte.
    - et une autre fonction qui permet d'ecrire les infos trouver dans le fichier créer.

    cette deuxieme fonction a besoin du nom du fichier je fais donc appel a GetNom() mais quand je fais GetNom() juste apres creerfichier() je recupere le on nom. Par contre quand il y a une focntion entre créerfichier() et GetNom() commme dans mon cas la fonction qui recupere les infos. Et bien la varaible qui contient le nom du fichier et modifié... alors que rien dans la fonction ne le demande et ne touche à cette variable ! La valeur est enfaite remplacer par un bout de texte du fichier dont je recupere les infos...

    Du coup je pense que ca doit venir de la memoire mais j'aimerais bien comprendre le comment du pourquoi de la chose .

    Voila j'espere que j'ai été clair et que vous pourrez m'aider.
    Est ce que par hazard, dans ta classe tu allloues de l'espace (ou que tu as suffisemment de place pour le stocker dans un buffer) pour sauvergarder le nom du fichier créé.
    Ta fonction GetNom() doit retourner un pointeur sur un espace alloué (new ou buffer suffisemment grand) en interne dans ta classe

    Raymond
    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
    Membre expérimenté Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Par défaut
    De deux choses l'une :
    - La réponse est 42
    - On est pas voyant, on devine pas les erreurs sans avoir le bout de code qui pose probleme sous les yeux


  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Par défaut
    Est ce que par hazard, dans ta classe tu allloues de l'espace (ou que tu as suffisemment de place pour le stocker dans un buffer) pour sauvergarder le nom du fichier créé.
    Ta fonction GetNom() doit retourner un pointeur sur un espace alloué (new ou buffer suffisemment grand) en interne dans ta classe
    Oui j'ai un char* NomFichier, membre privée de ma premier classe qui stock le nom mais cette variable est changé sans que je le veuille !


    voila le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            case 1 : result = CSA->RechercheVariantes(CheminCSALblEd->Text);break;
            case 2 : break;//Extraire infos Version PR;
            case 3 : result = XML->CreerFichier();
                     break;
            case 4 : result = XML->SetVersion(XML->GetNom(),CSA->mpInfosCSA->mVersion,"111","222","222");break;
            case 5 : result = XML->SetVariantes(XML->GetNom(),CSA->mpVariantes);break;
    Pour le case 4, je recupere bien le bon Nom avec getnom car aucune fonction n'a encore été appelé. Mais pour le case 5 le nom a été modifié pourtant ma fonction SetVersion ne fait rien pour !

    (SetVersion est censé ajouté des numero de version dans un fichier xml)
    (Setvariante est censé ajouté des nom de variantes de produit dans un fichier Xml)

    elles font toutes les deux appels aux fonctions de libxml2.

    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
     
      IMPORT_EXPORT class TXML
      {
    	public :
        __fastcall TXML(TComponent* Owner);
        int __fastcall CreerFichier(void);
        int __fastcall SetVersion(AnsiString filenameXML, AnsiString versionCSA, AnsiString versionPRE, AnsiString versionPRO, AnsiString versionIND);
        int __fastcall SetVariantes(AnsiString filenameXML, TStringList *listvariante);
        char* __fastcall GetNom(void);
     
    	private :
     
        char* NomFichierXML;
        TSaveDialog *SaveDialog1;
        TComponent  *mpXMLOwner;
        TStringList *mpContenu;
      };
    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
     
      IMPORT_EXPORT class TCSA
      {
    	public :
        __fastcall TCSA(TComponent* Owner);
        __fastcall ~TCSA();
        int __fastcall RechercheInfosCSA(AnsiString filenameCSA);
        int __fastcall RechercheVariantes(AnsiString filenameCSA);
     
        TFichier*    mpInfosCSA;
        TComposant*  mpComposantCSA;
        TStringList* mpVariantes;
        TStringList* mpPartName;
     
    	private :
     
        TStringList* mpFichierCSA;
      };
    voila pour le bout de code de mes classes.

    Vous voulez les fonctions ? elles sont longues en codes !

  5. #5
    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
    Citation Envoyé par adurandet Voir le message
    Oui j'ai un char* NomFichier, membre privée de ma premier classe qui stock le nom mais cette variable est changé sans que je le veuille !


    voila le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            case 1 : result = CSA->RechercheVariantes(CheminCSALblEd->Text);break;
            case 2 : break;//Extraire infos Version PR;
            case 3 : result = XML->CreerFichier();
                     break;
            case 4 : result = XML->SetVersion(XML->GetNom(),CSA->mpInfosCSA->mVersion,"111","222","222");break;
            case 5 : result = XML->SetVariantes(XML->GetNom(),CSA->mpVariantes);break;
    Pour le case 4, je recupere bien le bon Nom avec getnom car aucune fonction n'a encore été appelé. Mais pour le case 5 le nom a été modifié pourtant ma fonction SetVersion ne fait rien pour !

    (SetVersion est censé ajouté des numero de version dans un fichier xml)
    (Setvariante est censé ajouté des nom de variantes de produit dans un fichier Xml)

    elles font toutes les deux appels aux fonctions de libxml2.

    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
     
      IMPORT_EXPORT class TXML
      {
    	public :
        __fastcall TXML(TComponent* Owner);
        int __fastcall CreerFichier(void);
        int __fastcall SetVersion(AnsiString filenameXML, AnsiString versionCSA, AnsiString versionPRE, AnsiString versionPRO, AnsiString versionIND);
        int __fastcall SetVariantes(AnsiString filenameXML, TStringList *listvariante);
        char* __fastcall GetNom(void);
     
    	private :
     
        char* NomFichierXML;
        TSaveDialog *SaveDialog1;
        TComponent  *mpXMLOwner;
        TStringList *mpContenu;
      };
    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
     
      IMPORT_EXPORT class TCSA
      {
    	public :
        __fastcall TCSA(TComponent* Owner);
        __fastcall ~TCSA();
        int __fastcall RechercheInfosCSA(AnsiString filenameCSA);
        int __fastcall RechercheVariantes(AnsiString filenameCSA);
     
        TFichier*    mpInfosCSA;
        TComposant*  mpComposantCSA;
        TStringList* mpVariantes;
        TStringList* mpPartName;
     
    	private :
     
        TStringList* mpFichierCSA;
      };
    voila pour le bout de code de mes classes.

    Vous voulez les fonctions ? elles sont longues en codes !
    donc si je comprends bien :
    dans ta classe TXML, GetNom() retourne NomFichierXML
    et c'est ta fonction CreerFichier() qui crée le nom du fichier.

    on peut voir le code de TXML::GetNom et de TXML::CreerFichier() ?

    Raymond
    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
    .

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Par défaut
    oui carrement,

    mais ca ca marche c'est apres que la variabla nomfichier se fait ecraser par des trucs qui vuelent plus rien dire !

    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
     
    int __fastcall TXML::CreerFichier()
    {
       int result = CODE_ERREUR_CREATION_FICHIER;
       SaveDialog1 = new TSaveDialog(this->mpXMLOwner);
       SaveDialog1->Filter = XML_FILTRE;
       SaveDialog1->DefaultExt = EXT_FICHIER;
       if(SaveDialog1->Execute())
       {
         HANDLE HFile;
         if ( (HFile = CreateFile(SaveDialog1->FileName.c_str(),GENERIC_WRITE,FILE_SHARE_READ, NULL,CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
         {
            CloseHandle(HFile);
            mpContenu = new TStringList;
            mpContenu->Add(ENCODAGE_XML);
            mpContenu->Add(DEBUT_RACINE);
            mpContenu->Add(NOEUDS_PRINCIPAUX);
            mpContenu->Add(FIN_RACINE);
            mpContenu->SaveToFile(SaveDialog1->FileName);
            delete mpContenu;
            NomFichierXML = SaveDialog1->FileName.c_str();
            result = CODE_FICHIER_CREE;
         }
         else
         {
            result = CODE_FICHIER_EXISTANT;
         }
       }
       delete SaveDialog1;
       return result;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char* __fastcall TXML::GetNom(void)
    {
      return NomFichierXML;
    }

    je mets le code la fonction qui fait tout modifier au cas où (mais ca le fait aussi avec d'autre fonction) :

    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
     
    int __fastcall TXML::SetVersion(AnsiString filenameXML, AnsiString versionCSA, AnsiString versionPRE, AnsiString versionPRO, AnsiString versionIND)
    {
      int result = CODE_ERREUR_CHARGEMENT;
      xmlDocPtr fichierXML;
      xmlNodePtr racine;
      xmlNodePtr versions;
     
      // Ouverture du fichier XML
      fichierXML = xmlParseFile(filenameXML.c_str());
      if (fichierXML == NULL)
      {
        result = CODE_FICHIER_XML_INVALIDE;
      }
      else
      { // Récupération de la racine
        racine = xmlDocGetRootElement(fichierXML);
        if (racine == NULL)
        {
          result = CODE_FICHIER_XML_VIERGE;
          xmlFreeDoc(fichierXML);
        }
        else
        {//************ Chercher le noeud "versions" *************
     
          // Initialisation de l'environnement XPath
          xmlXPathInit();
          xmlXPathContextPtr ctxt = xmlXPathNewContext(fichierXML);
          if (ctxt == NULL)
          {
            result = CODE_ERREUR_SET_VERSION;
          }
          else
          {
            // Evaluation de l'expression XPath
            xmlXPathObjectPtr xpathRes = xmlXPathEvalExpression("/projet/versions", ctxt);
            if (xpathRes == NULL)
            {
              result = CODE_ERREUR_SET_VERSION;
            }
            else
            {
              if (xpathRes->type != XPATH_NODESET)
              {
                result = CODE_ERREUR_SET_VERSION;
              }
              else
              {
                versions = *xpathRes->nodesetval->nodeTab;
                xmlSetProp(versions, "csa", versionCSA.c_str());
                xmlSetProp(versions, "pre", versionPRE.c_str());
                xmlSetProp(versions, "pro", versionPRO.c_str());
                xmlSetProp(versions, "ind", versionIND.c_str());
                xmlSaveFile(filenameXML.c_str(), fichierXML);
                result = CODE_SET_OK;
              }
              xmlXPathFreeObject(xpathRes);
            }
            xmlXPathFreeContext(ctxt);
          }//*************************************
        }
        xmlFreeDoc(fichierXML);
      }
      return result;
    }
    voila si vous trouvez une reponse ...

    ce que je pense c'est que ma variable Nomfichier doit etre stocker dans la memoire et qu'en faisant appel à une fonction le programme a besoin de memoire et il mets des trucs a la place de la variable nomfichier.

    Mais je sais pas commetn eviter ça et puis c'est quand meme pas normal ... surtout que ce qui est mis a la place de mon nom de fichier ca change tout le temps.

  7. #7
    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
    OK, je me doutais bien d'un truc comme cela:

    Dans ta fonction TXML::CreerFichier(), tu as une variable SaveDialog1 qui possède le nom du fichier sous forme de std::string

    tu fais NomFichierXML = SaveDialog1->FileName.c_str();
    et ensuite tu quitte la fonction en faisant un delete de SaveDialog1

    donc lors du delete, le conteneur std::string qui contient le nom du fichier est détruit et ton pointeur NomFichierXML pointe sur n'importe quoi qui n'existe plus (mais qui a existé)

    ce qu'il te faut modifier:
    dans la déclaration de ta classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    string NomFichierXML; // au lieu de char* NomFichierXML;
    dans ta classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // fonction CreerFichier
    NomFichierXML = SaveDialog1->FileName; // au lieu de NomFichierXML = SaveDialog1->FileName.c_str();
     
    // fonction GetNom
    char* __fastcall TXML::GetNom(void)
    {
      return NomFichierXML.c_str(); // au lieu de return NomFichierXML;
    }
    Raymond
    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
    .

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Dans le cas racine == NULL tu fais 2 fois l'appel à xmlFreeDoc(fichierXML), ce qui n'est pas top.

    MAT.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Par défaut
    Citation Envoyé par ram_0000 Voir le message
    OK, je me doutais bien d'un truc comme cela:

    Dans ta fonction TXML::CreerFichier(), tu as une variable SaveDialog1 qui possède le nom du fichier sous forme de std::string

    tu fais NomFichierXML = SaveDialog1->FileName.c_str();
    et ensuite tu quitte la fonction en faisant un delete de SaveDialog1

    donc lors du delete, le conteneur std::string qui contient le nom du fichier est détruit et ton pointeur NomFichierXML pointe sur n'importe quoi qui n'existe plus (mais qui a existé)

    ce qu'il te faut modifier:
    dans la déclaration de ta classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    string NomFichierXML; // au lieu de char* NomFichierXML;
    dans ta classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // fonction CreerFichier
    NomFichierXML = SaveDialog1->FileName; // au lieu de NomFichierXML = SaveDialog1->FileName.c_str();
     
    // fonction GetNom
    char* __fastcall TXML::GetNom(void)
    {
      return NomFichierXML.c_str(); // au lieu de return NomFichierXML;
    }
    Raymond

    Ok je vais tester ça !

    merci bcp

    Sinone st ce que mon code en lui même est correct ou propre ?

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Salut,

    Dans le cas racine == NULL tu fais 2 fois l'appel à xmlFreeDoc(fichierXML), ce qui n'est pas top.

    MAT.
    Ah oui j'avais pas vu !

    merci

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 114
    Par défaut
    ram_0000 : j'ai testé la solution mais ca ne amrche tojours pas ! ...

    Edit 1:

    enaite c 'est bon j'ai juste fait une petite erreur. merci de votre aide !

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

Discussions similaires

  1. [JSP] Frame a contenu variable
    Par christopheJ dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 25/03/2010, 12h18
  2. Réponses: 5
    Dernier message: 12/05/2005, 10h49
  3. Réponses: 6
    Dernier message: 16/03/2005, 14h44
  4. [LG]Variable non initialisée.
    Par Loceka dans le forum Langage
    Réponses: 3
    Dernier message: 18/11/2004, 18h36
  5. Réponses: 6
    Dernier message: 13/05/2004, 15h40

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