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 :

[c++] new écrit à une adresse existante !?!


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 127
    Par défaut [c++] new écrit à une adresse existante !?!
    Bonsoir à tous !

    Je me suis remis au C++ histoire de me décrasser (j'ai fait du LUA pendant 9 mois ), et la ca fait 2h que je me prends la tête sur un problème...

    En fait je me suis fixé comme but de faire une appli en C++/wxWidgets permettant de dessiner des plans d'appartement. Je commence doucement, avec murs et "nodes" points de ralliement des murs (un mur a donc une node de départ, et une d'arrivée).

    Tout va bien, mais la, j'ai fait en sorte que clic du bouton milieu sur un mur le divise en deux. Et parfois ca fait n'imp ! Jme suis demandé d'où venait l'erreur dans mon code, mais à force de pas trouver, me suis décider à afficher les adresses des différents nodes et murs (pour l'instant un seul mur que je divise).

    Et la, SURPRISE !!! Je me rends compte que la nouvelle node que je crée pour définir le point milieu du mur est en fait allouée par new à la place d'une des deux nodes existantes !!!

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ADNode* ADNode::getCenter(ADNode *begin, ADNode *end)
    {
    	assert(begin != NULL);
    	assert(end != NULL);
     
    	std::cout << "Get center of " << *begin << " and " << *end << std::endl;
    	int x = (begin->getX() + end->getX()) / 2;
    	int y = (begin->getY() + end->getY()) / 2;
    	ADNode *center = new ADNode(x, y);
    	std::cout << "Found : " << *center << std::endl;
    	return center;
    }
    Et voici le résultat obtenu dans la console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Get center of (0x1031b70) (10, 30) and (0x1031bb0) (210, 30)
    [NEW NODE] (0x1031b70) (110,30) 1 nodes total
    Found : (0x1031b70) (110, 30)
    (les premières parenthèses sont bien sur l'adresse du pointeur, et les suivantes sont le point mathématique).

    On remarque bien qu'il crée la nouvelle node à la place d'une existante ! Jme disais bien, aussi : pour mes classes j'ai un compteur d'instances, et à la fin du programme quand j'ai tout nettoyé, j'affiche ce compteur pour être sûr de rien avoir oublié. Et parfois il est NEGATIF pour les nodes, et parfois positif... Trop bizarre cette histoire !

    Evidemment, hors de question d'utiliser le placement new. Quelqu'un saurait pourquoi new m'écrase une zone précédemment allouée ?

    Merci beaucoup de votre aide les roxxors !

    Bonne soirée à tous !

    Lideln

  2. #2
    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,

    C'est possible de voir le code du constructeur et celui de l'opérateur de sérialisation d'ADNode ?

    MAT.

  3. #3
    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 : 50
    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
    Par défaut
    A priori, la principale raison que je devine, c'est que ton objet pointé par begin a déjà été détruit avant d'appeler la fonction, et donc que sa mémoire est de nouveau disponible. Il faudrait pour confirmer ça avoir un programme minimaliste et complet qui reproduise le problème. Au minimum, il faudrait voir les constructeurs par recopie, destructeurs, opérateur= et opérateur<< de ADNode. Une autre façon de faire est de mettre du trace/breakpoint dans le destructeur afin de tester.

    Question annexe, mais peut-être reliée... Pourquoi tant de pointeurs ? Je ne connais pas ta classe ADNode, mais a priori, je la manipulerais sous forme de valeur, et en passage d'argument, j'utiliserais des ADNode const &
    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.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 127
    Par défaut
    Hello,

    Merci pour vos réponses !


    @Mat007 :
    constructeur :
    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
     
    ADNode::ADNode() : _x(0), _y(0), _selected(false)
    {
    	++_count;
    	cout << "[NEW NODE] (" << this << ") (00,00) " << _count << " nodes total" << endl;
    }
     
    ADNode::ADNode(int x, int y) : _x(x), _y(y), _selected(false)
    {
    	++_count;
    	cout << "[NEW NODE] (" << this << ") (" << _x << "," << _y << ") " << _count << " nodes total" << endl;
    }
     
    ADNode::~ADNode()
    {
    	_count--;
    	cout << "[DEL NODE] (" << this << ") (" << _x << "," << _y << ") " << _count << " nodes total" << endl;
    }
    La surchage de << :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::ostream& operator<<(std::ostream& os, ADNode& node)
    {
    	os << "(" << &node << ") (" << node._x << ", " << node._y << ")";
    	return os;
    }

    @JolyLoic :

    Comme tu peux le voir dans le code que j'ai fourni juste au dessus, je trace le constructeur et le destructeur. Donc ce n'est pas une ADNode qui a été détruite puis remplacée par la nouvelle (enfin à priori).

    Code complet de la fonction getCenter (appelé par la fonction divide()) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ADNode* ADNode::getCenter(ADNode *begin, ADNode *end)
    {
    	assert(begin != NULL);
    	assert(end != NULL);
     
    	std::cout << "Get center of " << *begin << " and " << *end << std::endl;
    	int x = (begin->getX() + end->getX()) / 2;
    	int y = (begin->getY() + end->getY()) / 2;
    	ADNode *center = new ADNode(x, y);
    	std::cout << "Found : " << *center << std::endl;
    	return center;
    }
    Pour la question des pointeurs plutot que des références, a vrai dire je sais pas Jsuis habitué à utiliser pointeur. Question optimisation c'est aussi rapide, mais c vrai qu'il parait que c'est plus secure d'utiliser les références. Apres jsais pas, j'ai été habitué à bosser avec pointeurs en fait.

    Mais comme tu dis, ca n'explique pas le pourquoi de ce problème
    A noter que ca n'arrive pas tout le temps, mais très très très souvent quand meme (genre jpeux pas diviser une deuxième fois, ca, ca marche jamais)

    Voila, si ca peut vous aider... Sinon je peux commit d'autres bouts de code... Ya pas de secret lol ^^

    Merci à vous !

  5. #5
    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 : 50
    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
    Par défaut
    Citation Envoyé par Lideln
    Pour la question des pointeurs plutot que des références
    Ce n'était pas tant pointeurs vs références que pointeurs vs données sur la pile.

    Citation Envoyé par Lideln
    Voila, si ca peut vous aider... Sinon je peux commit d'autres bouts de code... Ya pas de secret lol ^^
    Le bout de code où tu crée tes nodes ? L'idéal serait un programme de test complet et compilable, de 5 lignes dans le main, où tu crées tes nodes, appelle getCenter, détruit les nodes, et qui reproduise le plantage.
    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.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 127
    Par défaut
    Tout va mieux !!! Fausse alerte ! (comme d'hab )

    En fait ca venait d'une modif que j'avais faite il y a peu : avant quand je créais un mur, dans son constructeur je lui créait 2 nodes par défaut. Jme suis dit que c'était débile et porteur de risques de fuites etc, alors j'ai commenté les lignes. Sauf que donc les pointeurs _begin et _end n'étaient pas initialisés (arf) et donc ca faisait tout partir en vrille !

    Merci pour votre aide, un instant j'ai eu peur que new ait changé de comportement durant ma longue absence du c++

    Donc fausse alerte, enfin si on peut dire, et merci pour votre aide, ca m'a forcé à chercher un peu plus en profondeur et à remarquer les lignes fautives

    Bonne nuit merci encore !

    Lideln

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Pense à cliquer sur

Discussions similaires

  1. Redirection d'un site vers une adresse dans UNE NEW FENETRE
    Par Mout85 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 20/06/2005, 09h40
  2. Réponses: 5
    Dernier message: 25/03/2003, 17h27
  3. Réponses: 2
    Dernier message: 26/02/2003, 11h47
  4. commande dos pour résoudre une adresse ip
    Par stephy dans le forum Développement
    Réponses: 2
    Dernier message: 17/12/2002, 14h04
  5. Comment récupérer une adresse MAC ?
    Par psau dans le forum Développement
    Réponses: 7
    Dernier message: 19/07/2002, 17h26

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