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 :

Comment échanger références et pointeurs ?


Sujet :

C++

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 31
    Points : 10
    Points
    10
    Par défaut Comment échanger références et pointeurs ?
    Bonjour à tous,

    Question bête aujourd'hui, je suis confronté à des problèmes de gestion de mémoire assez opaques pour moi que j'essaie de résoudre comme je peux... Du coup je reviens vers ce forum qui m'a déjà bien aidé pour mon algo du moment.

    Donc, pour passer d'une référence à un pointeur et vice-versa, je voudrais juste confirmation (ou non) qu'on peut sans problèmes subtils écrire ça svp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Objet* p = new Objet();
    Objet& r = *p; // pointeur => référence
    Objet* p2 = &r; // référence => pointeur
    delete p2;
    Merci d'avance

    PS : en fait j'ai notamment cette fonction qui semble poser souci, en effet j'ai bien l'impression que j'ai des nœuds qui disparaissent mystérieusement dans mon programme à cause d'elle :

    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
     
    Noeud& Noeud::insererNouveauNoeud(unsigned int posFilsAScinder, unsigned int nbCaracteresARetrancher) // scinde une arête du noeud courant en deux, en y insérant un nouveau noeud après le nombre de caractères indiqué (adapté pour ukkonen)
    {
        Noeud& filsAScinder = *fils[posFilsAScinder]; // référence vers le fils dont on va scinder l'arête
        unsigned int indexDebutFils = filsAScinder.getIndexDebut(); // on récupère son index de début
        filsAScinder.setIndexDebut(indexDebutFils + nbCaracteresARetrancher); // on met à jour le début de l'ancien fils en conséquence
        Noeud* pnouveau = new Noeud(indexDebutFils, indexDebutFils + nbCaracteresARetrancher - 1, 0); // on crée un nouveau noeud avec cet index de début et l'index de fin au bon endroit
     
        pnouveau->nouveauFils(&filsAScinder);
        setFils(pnouveau, posFilsAScinder);
     
        return *fils[posFilsAScinder];
    }
     
    void Noeud::setFils(Noeud* n, unsigned int index)
    {
        fils[index] = n; // c'est un vector de pointeurs vers des Noeud
        fils[index]->pere = this;
    }
     
    unsigned int Noeud::nouveauFils(Noeud* n)
    {
        n->pere = this;
        fils.push_back(n);
        return fils.size() - 1;
    }

  2. #2
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

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

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Bonjour

    Si tu récupères la Noeud & retournée par Noeud::insererNouveauNoeud et que tu rappelles Noeud::insererNouveauNoeud qui appelle Noeud::nouveauFils qui appelle vector<T>::push_back. Si vector<T>::push_back fait une réallocation, tous les itérateurs, références et pointeurs sur les éléments du vector<T> sont invalides.

    Concernant, ton premier code, il est correct en C++98 (même si on évite de pouvoir créer une dangling reference (référence "invalide") (c'est le cas de r après le delete)) mais en C++11 on utiliserait un std::unique_ptr.

    J'ai l'impression que le code est inutilement compliqué. Pourquoi as-tu besoin de l'allocation dynamique (gérée à la main) et surtout : utilises-tu le polymorphisme d'inclusion (héritage) ?
    Dans Noeud::insererNouveauNoeud, tu fais Noeud* p = new Noeud(...);, autant faire Noeud n(...);.

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 31
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Je fais l'allocation gérée à la main justement pour que le vector ne fasse pas de ré-allocations, puisque c'est du coup un vector de pointeurs. A l'origine je ne l'avais pas fait de cette manière : c'était un vector de Noeud et comme les Noeuds contiennent des pointeurs vers d'autres Noeud, c'était un vrai casse-tête à gérer dès qu'un Noeud était déplacé en mémoire (notamment justement lors des ré-allocations par des opérations de vector).

    J'espérais que le fait de gérer l'allocation à la main me permettrait de venir à bout de l'erreur de mémoire que je rencontre avec mon algo mais malheureusement ce n'est pas encore le cas.

  4. #4
    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
    Citation Envoyé par Tokapi Voir le message
    A l'origine je ne l'avais pas fait de cette manière : c'était un vector de Noeud et comme les Noeuds contiennent des pointeurs vers d'autres Noeud, c'était un vrai casse-tête à gérer dès qu'un Noeud était déplacé en mémoire (notamment justement lors des ré-allocations par des opérations de vector).
    C'est parce que dans ce cas, il aurait fallu utiliser des indices pour tes liens, plutôt que des pointeurs.
    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.

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 31
    Points : 10
    Points
    10
    Par défaut
    Ca aurait été d'autant plus compliqué que chaque Noeud contient sa liste de fils (ils n'étaient pas contenus dans un tableau à part, mais plutôt dans des tableaux imbriqués)

  6. #6
    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
    Bon, on va arrêtez de faire du bricolage avec des pointeurs nus et des allocations dynamiques à la petite semaine, OK ?

    Utilisez des pointeurs intelligents.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 31
    Points : 10
    Points
    10
    Par défaut
    J'y penserai, mais en l'occurrence la gestion de mémoire est loin d'être compliquée et entièrement gérée par la classe : on ne fait que créer des Noeud et stocker leurs pointeurs dans des tableaux imbriqués, puis on dés-alloue tout à la destruction du Noeud-racine. En fait il s'avère que l'erreur que je rencontre n'a finalement pas l'air d'être une erreur de gestion de mémoire mais un problème d'algo. Merci quand même.

Discussions similaires

  1. [C#] Comment changer dans une chaine
    Par onouiri dans le forum ASP.NET
    Réponses: 7
    Dernier message: 13/05/2004, 13h17
  2. Comment changer l'heure système ?
    Par Lung dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 26/04/2004, 10h24
  3. Comment changer des mots dans un fichier?
    Par ptitbonum dans le forum Linux
    Réponses: 5
    Dernier message: 07/04/2004, 23h42
  4. comment changer d'attribut de fonte dans un Tlabel?
    Par sb dans le forum Composants VCL
    Réponses: 3
    Dernier message: 21/08/2002, 16h53
  5. TextOut : comment changer de font
    Par Freakazoid dans le forum DirectX
    Réponses: 2
    Dernier message: 15/07/2002, 20h46

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