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 conceptuel de pointeur


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut Problème conceptuel de pointeur
    Bonjour,
    Je débute en c++ et je me trouve confronté à un problème de pointeur ...
    Grosso modo en pseudo code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Pour chaque element d'un vecteur :
    Objet o = vector.back();
    Objet * t = transform( & o );
    if( t ) cout << t ;
    delete t;
    t = nullptr;
    Fin pour
    Sauf que je récupére un message d'erreur qui me dit que le programme supprime 2 fois le même objet ... ce qui est vrai.
    Mes besoins : récupérer un objet venant d'un vecteur et le passer à une fonction en pointeur pour le transformer.
    J'ai essayé avec un "shared_ptr" avec le meme résultat.
    Qu'est ce que ça vaut de ne pas faire vu que l'objet crée en amont sera détruit par le programme ?
    Ou auriez vous une solution ?
    Merci,

  2. #2
    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 : 49
    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
    Ce serait bien d'avoir du vrai code (réduit à l'essentiel) plutôt que du pseudo code. En particulier, elle fait quoi ta fonction transform ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    La fonction transform prend en argument un pointeur sur l'objet, transforme éventuellement cet objet ou renvoi un pointeur null.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Objet* MyObjet::transform( Objet * o )
    {
    if ( o.getName().compare( "ok") == 0 ) return o;
    return nullptr;
    }
    Je conçois que le pseudo code ne soit pas terrible mais le code l'est encore plus ...

  4. #4
    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
    Bah c'est plutôt clair : tu fais un delete sur un objet qui n'est même pas alloué dynamiquement.
    Ta fonction transform retourne le pointeur passé en paramètre, dans ton pseudo-code c'est en rien un objet dynamique.
    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.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Et plutôt que de se faire des nœuds au cerveau avec ces pointeurs nus tout moisi, pensez à utiliser des pointeurs intelligents qui vous forcent à vous poser les bonnes questions (qui est propriétaire de l'objet, il est partageable ou pas, etc...).

  6. #6
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    J'ai nettoyé le code, isolé les élements pour arriver à ça :

    Header :
    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
     
    #ifndef VEHICULE_INCLUDED
    #define VEHICULE_INCLUDED
     
    #include <vector>
     
    class Vehicule
    {
    	public:
    		Vehicule();
    		Vehicule(std::string n, int i);
    		~Vehicule();
    		std::string getName();
    		void setName(std::string n);
    		int getRoue();
    		void setRoue(int i);
    		Vehicule* transform( Vehicule &other );
     
    	private:
    		std::string name;
    		int roue; 
    };
     
    #endif //VEHICULE_INCLUDED
    Definition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <string>
    #include "Vehicule.h"
     
    using namespace std;
     
     
    Vehicule::Vehicule(){}
    Vehicule::Vehicule(string n, int i) : name(n), roue(i){}
    Vehicule::~Vehicule(){}
    string Vehicule::getName(){ return name ;}
    void Vehicule::setName(string n){ name = n;}
    int Vehicule::getRoue(){ return roue ;}
    void Vehicule::setRoue(int i) {roue = i ;}
    Main :

    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
     
    #include <iostream>
    #include <memory>
    #include <string>
    #include "Vehicule.h"
     
    using namespace std;
     
     
    shared_ptr<Vehicule> transform_shared( shared_ptr<Vehicule> other )
    {
    	if( other -> getName().compare( "ok" ) == 0 ) return other;
    	return nullptr;
    }
    Vehicule* transform( Vehicule* other )
    {
    	if( other -> getName().compare( "ok" ) == 0 ) return other;
    	return nullptr;
    }
    Ce code utilise des pointeurs bruts :
    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
     
    int main()
    {
     
    Vehicule v1( "ok", 4 );
    Vehicule* v2 = new Vehicule;
    v2 = &v1;
     
    v2 = transform( v2 );
     
    if (v2) cout << "V2 " << v2 -> getName() << endl;
    cout << "V1 " << v1.getName() << endl;
    //delete v2; -> Fonctionne
    v2 = nullptr;
     
    cout << "END" << endl;
    }
    Et avec une valeur "ok", la fonction transforme renvoi donc le meme pointeur et l'objet est supprimé 2 fois par le programme : quand le v1 est supprimé automatiquement et quand v2 est "delete" il l'est également. Par contre cela fonctionne si on ne fait pas de "delete" sur le pointeur brut. Il n'y a pas de problème de fuite mémoire, j'ai testé une autre version avec 1 Go de données et j'ai rien vu passé dans l'utilisation de la RAM. Mais comme j'ai lu quelque part qu'un pointeur brut non supprime c'est mal, avec un shared_ptr cela fonctionne très bien :
    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
     
    int main()
    {
     
    Vehicule v1( "ok", 4 );
    shared_ptr<Vehicule> v2( new Vehicule );
     
    v2 = transform( v2 );
     
    if (v2) cout << "V2 " << v2 -> getName() << endl;
    cout << "V1 " << v1.getName() << endl;
     
     
    cout << "END" << endl;
    }
    Merci, j'ai pu avancé dans ma réflexion grâce à vos remarques

  7. #7
    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
    Citation Envoyé par The_GuiGui Voir le message
    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
     
    #include <iostream>
    #include <memory>
    #include <string>
    #include "Vehicule.h"
     
    using namespace std;
     
     
    shared_ptr<Vehicule> transform_shared( shared_ptr<Vehicule> other )
    {
    	if( other -> getName().compare( "ok" ) == 0 ) return other;
    	return nullptr;
    }
    Vehicule* transform( Vehicule* other )
    {
    	if( other -> getName().compare( "ok" ) == 0 ) return other;
    	return nullptr;
    }
    Ce code utilise des pointeurs bruts :
    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
     
    int main()
    {
     
    Vehicule v1( "ok", 4 );
    Vehicule* v2 = new Vehicule;
    v2 = &v1;
     
    v2 = transform( v2 );
     
    if (v2) cout << "V2 " << v2 -> getName() << endl;
    cout << "V1 " << v1.getName() << endl;
    //delete v2; -> Fonctionne
    v2 = nullptr;
     
    cout << "END" << endl;
    }
    Ce code est tout autant faux en plus d'avoir une fuite mémoire. Si tu fais ton delete, que t'as beau commenté "fonctionne", tu vas delete... v1 qui n'est pas alloué dynamiquement.
    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.

  8. #8
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    Oui, c'est ce que j'ai voulu dire.
    Si on fait le delete, on supprime v1 et ça plante parce que le programme le supprime, si on le fait pas v1 est deleter automatiquement et cela fonctionne

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

Discussions similaires

  1. [Débutant] Problème conceptuel
    Par tetedemul dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 01/02/2007, 14h41
  2. problème avec les pointeurs en c
    Par dialloma dans le forum C
    Réponses: 14
    Dernier message: 01/01/2007, 21h22
  3. probléme avec les pointeurs
    Par killer_instinct dans le forum C++
    Réponses: 6
    Dernier message: 11/12/2006, 11h37
  4. [TTreeView] Problème avec les pointeurs d'objet
    Par BlackWood dans le forum Composants VCL
    Réponses: 2
    Dernier message: 02/07/2004, 14h31
  5. Problème passage de pointeur
    Par mick74 dans le forum MFC
    Réponses: 2
    Dernier message: 21/04/2004, 18h34

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