Bonjour,
J'ai un problème lorsque que je recopie un pointeur sur un objet, j'ai un attribut qui change :
Mon attribut passe de 5 à 77164360 . Les autres restent inchangés.
D'où peut venir le pb ? Merci.
Bonjour,
J'ai un problème lorsque que je recopie un pointeur sur un objet, j'ai un attribut qui change :
Mon attribut passe de 5 à 77164360 . Les autres restent inchangés.
D'où peut venir le pb ? Merci.
Bah je vois pas bien ou est le problème en fait, tu assigne un autre pointeur à _donnees (avec une fuite mémoire au passage si ça se trouve), donc c'est normal que a prenne la valeur de ce que tu lui donne.
Si le chiffre ne te convient pas, regarde plutôt du d'où vient le pointeur que tu passe à cette méthode...
Pourquoi l'attribut de 'inDonnees' change ? C'est impossible.
@haraelendil : C'est normal que le pointeur de _donnees change, mais il récupère la valeur de inDonnée dans les deux cas, alors que celui ci est uniquement copié entre les deux
Edit : est ce que tu es sûr que tes break points se suivent ? Genre est ce que tu as vérifié que la valeur de inDonnee est bien la même ?
Oui les break se suivent.
J'ai plusieurs objets qui ont le même setter. Sa bloque uniquement sur celui de 'Relocation'.
Et la valeur de inDonnee ? C'est bien la même à chaque foi ?
Après l'affectation, '_donnees' et 'inDonnees' pointent sur le même objet mais il y a eu un changement d'attribut. D'ailleur la valeur n'est jamais la même lorsque je fais plusieurs tests.
Ma question était :
Est ce que tu as vérifié que "inDonnee" pointe bien sur le même objet aux lignes (a) et (b) ? ( normalement ça devrait être le cas, mais normalement la valeur de "a" devrait être la même aussi )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 (a) a = inDonnee->get(); _donnee = indonnee; (b) a = inDonnee->get();
Oui. Même adresse mémoire à chaque fois.
Voila le code complet de la classe :
.cpp
.h
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
66
67
68
69
70 // En-tête ----------------------------------------------------------------------------------------------- #include "Relocation.h" #include "Donnees.h" // Constructeur ------------------------------------------------------------------------------------------ Relocation::Relocation() { _donnees = NULL; } // Destructeurs ------------------------------------------------------------------------------------------ Relocation::~Relocation() { } // Méthodes ---------------------------------------------------------------------------------------------- ////////////////////////////////// // Relocation ////////////////////////////////// void Relocation::RelocationAllTournne(H_P_C & mH_P_C) { for (int p1 = 0; p1 < mH_P_C.getNbrH_t(); ++p1) for (int p2 = 0; p2 < mH_P_C.getNbrH_t(); ++p2) if (p1 != p2) RelocationAllTourneePeriode(mH_P_C.get_ht(p1), mH_P_C.get_ht(p2)); } void Relocation::RelocationAllTourneePeriode(h_t & mH_t1, h_t & mH_t2) { for (int n1 = 0; n1 < mH_t1.getNbrTournee(); ++n1) for (int n2 = 0; n2 < mH_t1.getNbrTournee(); ++n2) RelocationTournee(mH_t1.getTournee(n1), mH_t2.getTournee(n2)); } void Relocation::RelocationTournee(Tournee & mTournee_1, Tournee & mTournee_2) { int position_i, position_j, periode_1 = mTournee_1.getPeriode(), periode_2 = mTournee_2.getPeriode(); bool continuer; Matrice<double> & ds = _donnees->getDs(); if (periode_1 != periode_2) { for (position_i = 1; position_i <= mTournee_1.getNbrClientsTour(); ++position_i) { Client & client_r = mTournee_1.getClientTour(position_i); if (client_r.getProfit(periode_2) > client_r.getProfit(periode_1)) { position_j = 0; continuer = true; while (position_j <= mTournee_2.getNbrClientsTour() && continuer == true) { if (mTournee_2.testInsertion(ds, client_r, position_j)) { mTournee_2.insererClientTournee(ds, client_r, position_j); mTournee_1.supprimerClient(ds, position_i); continuer = false; } ++position_j; } } } } } // Setters ----------------------------------------------------------------------------------------------- void Relocation::setDonnees(Donnees * inDonnees) { _donnees = inDonnees; }
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 #ifndef RELOCATION_H #define RELOCATION_H #include <QtGui> #include "H_P_C.h" class Donnees; class Relocation { private: Donnees * _donnees; public: Relocation(); ~Relocation(); void RelocationAllTourneePeriode(h_t & mH_t, h_t & mH_t2); void RelocationTournee(Tournee & mTournee_1, Tournee & mTournee_2); void RelocationAllTournne(H_P_C & mH_P_C); // Setters void setDonnees(Donnees * inDonnees); }; #endif // RELOCATION_H
Comme ça je vois pas... à part que ça devrait être :
Code : Sélectionner tout - Visualiser dans une fenêtre à part void setDonnees(Donnees * const inDonnees);
je viens de tester sur un autre PC. Meme probleme...
Tu peux faire voir la fonction getNbrPeriodes de Donnees.
@GrosLapin: Donnees const * const même.
Mon spider sense me dis que ca peut venir de memoire modifee alors qu'elle devrait pas, ce qui reviens a dire que le probleme est ailleurs. Avant de chercher ce probleme il faut eliminer la possibilite que le probleme sois dans la classe.
Deja, est-ce que tout ca se passe bien sur un thread unique?
Je vous donne le code qui appel le setter :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 void Fenetre::ouvrirInstance() { QString pathFichier = QFileDialog::getOpenFileName(this, "Ouvrir Instance MultiPeriode", NULL, NULL, NULL, NULL); QFile * fichier = new QFile(pathFichier.toStdString().c_str()); if (fichier->exists() && fichier->open(QIODevice::ReadOnly)) { _donnees = ouvrirInstanceFichier(fichier); majNouvelleInstance(); } else QMessageBox::warning(this, "Erreur", "Echec lors de l'ouverture de l'instance"); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 void Fenetre::majNouvelleInstance() { _resolutionExacte ->setDonnees(_donnees); _insertion ->setDonnees(_donnees); _DEUX_OPT ->setDonnees(_donnees); _OrExchange ->setDonnees(_donnees); _split ->setDonnees(_donnees); _insertionClientNonVisiter->setDonnees(_donnees); _suppressionInsertion ->setDonnees(_donnees); _crossover ->setDonnees(_donnees); _Relocation ->setDonnees(_donnees); }
Je tiens à préciser que sa fonctionnait bien depuis plus d'une semaine, et la sa bug ...
Le getter :
Code : Sélectionner tout - Visualiser dans une fenêtre à part int Donnees::getNbrPeriodes () { return _nbrPeriodes ; }
@Flob90 : Donnees const * const : non
J'avais un doute donc j'ai vérifié avant, si on met le pointeur en const ont peut pas faire l'affectation à un pointeur qui lui n'est pas const (sauf "const cast")
@GrosLapin: A oui, je mettais concentré sur les deux autres lignes
@OP: Tu oublies plein de "const" à plein d'endroit. Tu es en multi-thread ou en single-thread ? (pour reprendre la suggestion de Klaim).
A-tu essayé une exécution pas à pas ? Tu verras peut-être où est le changement.
Voila ma classe données :
Si je déclare l'attribut '_nbrClients' avant '_nbrPeriodes', le problème est sur l'attribut '_nbrClients'.
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 class Donnees { private: int _nbrPeriodes, _nbrClients, _nbrVehicules; [...] public: Donnees([...]); ~Donnees(); // Getters [...] int getNbrPeriodes (); int getNbrClients (); int getNbrVehicules(); };
Si le comportement est aussi hasardeux, ça vient peut être d'une toute autre partie du programme qui fait un peu n'importe quoi avec ta mémoire et tu t'en aperçois seulement là (genre un dépassement de tableau). Il pourrait être utile de tester ton appli avec Valgrind ainsi que de chercher de ce côté :
http://stackoverflow.com/questions/2...hecking-with-g
Si au lieu d'entiers sur tes trois variables, tu passes à des long long int, il se passe quoi ?
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager