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 :

problème de fonction avec des pointeurs


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut problème de fonction avec des pointeurs
    Bonjour,

    J'ai un souci de c++ concernant une fonction dont le but est de rassembler des pointeurs dans un seul tableau. Voici la fonction qui pose problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    vector<PE*> ATC::comptePE()
    {
        vector<PE*> tableau;
        for (int i=0;i<m_PEemp.size();i++)
        {
            for (int j=0;j<m_PEemp[i].getsize();j++)
            {
                tableau.push_back(m_PEemp[i].getPE(j));
            }
        }
        return tableau;
    }
    Voici l'idée : un objet nommé ATC possède un vecteur d'objets PEemp (emplacements de PE) qui chacun contiennent un vecteur de pointeursr d'objet PE. Cette fonction est créé afin de rassembler des pointeurs de PE en un seul tableau qui servira a comparer les PE. Piti schéma explicatif fait sous paint en pièce jointe.

    Cette fonction parcoure les PEemp avec la première boucle sur i puis les PE de chaque PEemp avec la seconde boucle sur j. Je pense que le problème vient de la fonction suivante, située dans la classe PEemp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PE* PEemp::getPE(int i) const {return m_PE[i];}
    Et je comprends paaaaaaaaas *sob*

    merci d'avance pour vos réponses.
    Images attachées Images attachées  

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    avec le message d'erreur ça serait mieux...
    heureusement la boule de cristal fonctionne ce soir.

    Ta fonction getPE est const et retourne un objet membre non const*, y'a fort à parier que le compilo t'insulte de quelque chose à ce niveau.
    Si ta fonction est const, le membre retourné doit être const, sinon la méthode ne doit pas être const.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    Désolé j'ai oublié de mentionner l'erreur. Mais le compilateur ne me renvoi aucune erreur, le programme s’exécute sans souci. Seulement au moment d'utiliser la fonction le programme plante et une fenêtre Windows s'affiche, "PGRM.exe a cessé de fonctionner."

    Et en utilisant le débugger il me renvoi une segmentation fault. Et en utilisant des cout un peu partout j'ai déterminé que c'est de la que vient l'erreur. En effet si j'écrit
    avant les deux boucles le bla apparaît dans la console avant le plantage, et il n'apparaît pas si je l'écrit avant le return.

    Encore désole de l'oubli ca n'arrivera plus (j'espère)

  4. #4
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par bl4cksky Voir le message
    Et en utilisant le débugger il me renvoi une segmentation fault. Et en utilisant des cout un peu partout j'ai déterminé que c'est de la que vient l'erreur. En effet si j'écrit
    avant les deux boucles le bla apparaît dans la console avant le plantage, et il n'apparaît pas si je l'écrit avant le return.
    Hello,

    Regardes la stacktrace au moment du plantage, tu sauras exactement d'où ça vient (sans avoir à mettre des cout partout).
    Les deux choses qui peuvent poser problèmes dans ces boucles sont tes fonctions : getsize() et getPE().

    Il est cependant possible que le plantage viennent de l'utilisation de ton tableau (qui je suppose est faite juste après que tu l'ai récupéré). Tu ne flush pas la sortie, il est donc possible que tes cout ne s'affichent pas immédiatement.
    Un pointeur sur un objet invalide est vite arrivé ..

    @Bousk, le tableau/vector est un membre de la classe, (vector de PE*), on peut donc retourner une copie d'un élément du vector dans une fonction const (ici un PE*) ? Pas de problèmes de const-correctness ici je pense.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Salut,

    D'abord merci de vos réponses rapides.

    @Iradrille
    Atta atta atta moi y'en a petit mec qui code depuis deux mois. Qu'est-ceque tu veux dire par "Tu ne flush pas la sortie"?

    quant à la fonction getsize(), voici son code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int PEemp::getsize() const {return m_PE.size(); }
    Et le tableau est utilisé dans cette fonction du main() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    vector<PE*> comptePE()
    {
        vector<PE*> PEatc,PEtot;
        PEatc=ATC->comptePE();
        for (int i=0;i<PEatc.size();i++)
        {
            PEtot.push_back(PEatc[i]);          
        }
        return PEtot;
    }
    Dans l'idéal il y aurait davantage que l'objet ATC comme stockage de PE, mais pour les tests je n'ai mis que celui-là. Avec ensuite une fonction de comparaison, mais que je n'ai pas encore codé. Pour l'instant le résultat est juste stocké dans le main() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<PE*> ToutesLesPE(comptePE());

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Où est gérée la durée de vie des objets PE?
    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
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Les PE sont créées dans le main au début du programme et détruites à la fin de celui-ci. Mais je ne suis pas sûr de comprendre le sens de ta question

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je voulais m'assurer qu'ils ne risquaient pas de disparaître sous les pieds du code les utilisant.
    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.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    C'est pour ca que j'utilise des pointeurs et pas directement les objets. de cette sorte je suis sûr que l'objet est toujours la.

  10. #10
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par bl4cksky Voir le message
    Atta atta atta moi y'en a petit mec qui code depuis deux mois. Qu'est-ceque tu veux dire par "Tu ne flush pas la sortie"?
    En fonction du système (et du compilo probablement), les cout ne sont pas instantanés.

    Il sont affichés quand il y a un retour à la ligne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::cout << "a ";
    Sleep(3000); // attente 3sec, pas portable, juste pour l'exemple
    std::cout << "b" << std::endl;
    Ici "a" et "b" seront probablement affichés en même temps, après l'attente de 3 secondes.

    Est-ce que tu utilises tes pointeurs après les avoir rassemblés dans un vector ? (Pour afficher une propriété de tes objets par exemple)
    Je pense, comme Médinoc, que ça vient de là, tu dois avoir un pointeur invalide quelque part.

    Montre nous le bout de code qui crée tes objets PE pour voir.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    je créé les PE dans un tableau de PE déclaré dans le main() et je les ajoute avec une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void ajoutPE(PE PEAj)          {m_PEs.push_back(PEAj);}
     
    int main()
    {
    std::vector<PE> m_PEs;
    ajoutePE(PE(string type))               //appelle PE() le constructeur de la classe PE, et type le nom de la PE (c'est le seul attribut)
    ....
    return 0;
    }
    Ensuite je déclare dans la classe ATC un tableau de vecteur d'emplacement de PE qui contient un certain nombre d'emplacements définis dans le constructeur de la classe PEemp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<PEemp> m_PEemp;
    Et chaque emplacement possède un certain nombre de pointeurs de PE dans un vecteur, que je déclare avec une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    std::vector<PE*> m_PE;
     
    void PEemp::ajoutePE(PE* pe)
    {
        if (m_PE.size()<m_nbemp)      //m_nbemp le nb max de PE que l'emplacement peut contenir, et m_PE les Pe de cet emplacement
        {
            m_PE.push_back(pe);
        }
        else                        {cout << "Il n'y a plus de place!!" << endl;}
    }

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    Si ça peut vous aider le déboguer me renvoi l'erreur "Segmentation Fault"
    avec la liste d'erreurs suivante :
    #0 0043820C	std::vector<PEemp, std::allocator<PEemp> >::size() const () (??:??)
    #1 00401EC5	ATC::comptePE() () (??:??)
    #2 0040E11A	comptePE() () (??:??)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour que ça segfault dans un vector::size(), il faut que le pointeur vers ton vecteur soit invalide.
    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.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    @Médinoc

    Merci je vois bien ce que tu veux dire, mais comment le résoudre? Le problème doit venir de la boucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i=0;i<m_PEemp.size();i++)
    mais je ne vois pas ce qui cloche... M_PEemp est un vecteur déclaré dans la classe ATC, je ne vois pas ce qui peut poser problème...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    On est sûr que this est valide?
    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.

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 38
    Points : 24
    Points
    24
    Par défaut
    ??? ben je ne vois pas pourquoi il ne le serait pas.

  17. #17
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par bl4cksky Voir le message
    ??? ben je ne vois pas pourquoi il ne le serait pas.
    La bonne question est plutôt : pourquoi serait il d'office valide

    This n'est jamais qu'un pointeur, c'est à dire, une valeur numérique entière (généralement non signée) qui correspond à l'adresse mémoire à laquelle l'objet est sensé se trouver.

    Le problème, c'est que, si l'objet a été détruit -- ne serait-ce que parce qu'on est sorti de la portée dans laquelle il a été construit de manière statique (comprends : sans avoir recours à l'allocation dynamique de la mémoire) -- mais qu'on avait récupéré l'adresse de cet objet "par ailleurs", this devient invalide, vu que l'objet n'existe plus, et this pointe donc vers potentiellement beaucoup de chose, mais très rarement vers l'objet que l'on espère

    Les erreurs de segmentation sont généralement dues au fait que l'on essaye d'accéder à une adresse invalide, soit parce que l'on essaye d'accéder à l'élément se trouvant à l'index X d'un tableau qui n'en contient que maximum X+1, soit parce qu'on essaye d'accéder à une adresse mémoire qui correspond à un objet qui a déjà été détruit.

    La question de Médinoc est donc plus que sensée, tu ne trouves pas
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Probléme de pointeur avec des pointeurs de char *
    Par marime dans le forum Débuter
    Réponses: 4
    Dernier message: 30/09/2013, 13h14
  2. Réponses: 47
    Dernier message: 29/05/2011, 23h17
  3. Problème avec des pointeurs
    Par Darick dans le forum C
    Réponses: 4
    Dernier message: 15/05/2008, 09h43
  4. problème char-actéristique avec des pointeurs
    Par Antigonos Ier Gonatas dans le forum C
    Réponses: 11
    Dernier message: 16/04/2007, 21h22
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39

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