Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1313 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Surcharge de l'opérateur = + Appel non souhaité à delete

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Surcharge de l'opérateur = + Appel non souhaité à delete

n°1589463
nathan_g
Posté le 20-07-2007 à 15:54:33  profilanswer
 

Bonjour,
 
J'ai créé une classe Article qui contient un pointeur sur une zone mémoire alloué.
Par propreté, j'ai donc créé un opérateur de destruction de cette zone pour éviter de bloquer la mémoire lorsque ces objets ne sont plus utilisé :
 

Code :
  1. class Article
  2. {
  3. ~Article()
  4. {
  5. delete [] tabdoub;
  6. }
  7. double* tabdoub;
  8. }


 
J'ai également créé un opérateur d'égalité afin de créer un objet "Article" de contenu identique à un autre.
Pour cela, bien évidemment, j'ai une boucle qui parcourt le tableau tabdoub et recopie tous ses éléments dans le nouvel objet :
 

Code :
  1. void Article::operator=(Article art_orig)
  2. {
  3. //recopie des éléments du tableau tabdoub de art_orig
  4. // après l'allocation dynamique nécessaire
  5. }


 
Tous cela fonctionne bien jusqu'à la fin de l'opérateur. Mais valgrind m'a signalé une erreur qui m'a échapé. En effet, par exemple, si dans le code,  j'écris :
 

Code :
  1. Article art1,art2;
  2. ...
  3. art2 = art1;


 
L'article art2 devient bien une copie de art1, mais, à la fin de l'appel à cet opérateur d'égalité, dans la procédure de recopie, le destructeur ~Article est appelé pour détruire la copie de art1 passé en argument de l'opérateur d'égalité (ie. art_orig). Ce destructeur détruit alors la zone alloué au tableau tabdoub de art_orig qui se trouve être la même que celle de art1 ! Ainsi, le contenu du tableau de art1 est également une zone mémoire effacée car elle est indentique à celle de art_orig !
 
 
Comme éviter ce problème ? Je souhaiterais quand même, par propreté, conserver ce destructeur qui est, normalement, nécessaire.
J'espère avoir été à peu près clair dans mes explications.
 
Cordialement

mood
Publicité
Posté le 20-07-2007 à 15:54:33  profilanswer
 

n°1589512
jojoleping​ouin
Posté le 20-07-2007 à 16:39:38  profilanswer
 

Bonjour,
 
Est-ce que tu pourrais préciser ceci ?

Code :
  1. void Article::operator=(Article art_orig)
  2. {
  3.       //recopie des éléments du tableau tabdoub de art_orig
  4.       // après l'allocation dynamique nécessaire
  5. }

Merci  :)

n°1589517
nathan_g
Posté le 20-07-2007 à 16:49:57  profilanswer
 

Bonjour,
 
Je veux simplement mentionner que l'opérateur d'égalité est écrit comme :
 

Code :
  1. void Article::operator=(Article art_orig)
  2. {
  3. int i;
  4. nmax = art_orig.val_nmax(); // Valeur du nombre maximal de points contenu dans le tableau tabdoub. Il s'agit d'un membre de art_orig auquel val_nmax() est la méthode d'accès
  5. for(i=0;i<nmax;i++)
  6. {
  7. tabdoub[i] = art_orig.val_tabdoub(i);    // Valeur du ième élément du tableau tabdoub de art_orig, l'article dont on cherche à faire une copie dans this
  8. }
  9. // Avant la sortie de l'opérateur , un appel par défaut au destructeur de Article et appliqué à art_orig est appelé
  10. // Il détruit le pointeur tabdoub de art_orig qui pointe vers la même zone que art1
  11. // Il n'y a donc pas conservation des valeurs du tableau tabdoub de art1
  12. }


 
Est-ce que mon problème est un peu plus claire ?
Il y a sans doute plusieurs solutions à ce problème mais je voidrais essayer de trouver quelque chose le plus propre possible.
 
Cordialement

n°1589528
jojoleping​ouin
Posté le 20-07-2007 à 17:01:01  profilanswer
 

Ajoute un constructeur de copie

Code :
  1. Article::Article(const Article & art_orig)

et transforme ton

Code :
  1. void Article::operator=(Article art_orig)

en

Code :
  1. void Article::operator=(const Article & art_orig)


Ca devrait aller mieux apres :).
 
edit: vire le void foireux....

Message cité 1 fois
Message édité par jojolepingouin le 20-07-2007 à 17:34:45
n°1589551
nathan_g
Posté le 20-07-2007 à 17:23:39  profilanswer
 

OK, je vais vérifier mais quel est l'intérêt d'un constructeur de copie par rapport à l'opérateur =.
 
Les deux réalise le même travail, non ? :
 
art2 = Article(art1);
art2 = art1;
 
sont deux écritures équivalentes ?
 
Est-ce que ton constructeur par recopie sera appelé lors de l'utilisation de l'opérateur " = " et permettra de faire une copie de art1 sous la forme de art_orig, avec des zones mémoires allouées distinctes entre ces deux objets ?
 
Merci déjà de ton aide,

n°1589562
jojoleping​ouin
Posté le 20-07-2007 à 17:34:14  profilanswer
 

Bah comme dirait Taz (en moins diplomatique bien sur), surcharger l'operateur= sans refaire un constructeur de copie ca sert juste a chopper des vieux bugs (un peu comme si on redefinit operateur+ sans refaire operateur+=).
 
Donc tu fais ca:

Code :
  1. Article::Article(const Article & art_orig)
  2. {
  3.    (*this) = art_orig;
  4. }

Et apres ca marchera mieux.
 
Sinon pour ton bug, tu passes art_orig en copie ici, donc ca appelle le constructeur de copie par défaut de ton Article(qui copie juste le pointeur), a la fin de ta methode, art_orig est détruit par ton destructeur et donc t'as tout corrompu.

Code :
  1. void Article::operator=(Article art_orig)

n°1589566
nathan_g
Posté le 20-07-2007 à 17:47:59  profilanswer
 

Merci de ces précisions mais, maintenant j'ai un stackoverflow en message d'erreur et je n'arrive même pas à entrer dans l'opérateur d'égalité ! Le programme s'arrête avant !
 
J'ai bien compris d'où venait mon problème initial, de la destruction d'une zone mémoire que j'utilisais par la suite comme tu le précises.
 
Par rapport à ce nouveau problème, est-ce que je dois conserver l'opérateur d'égalité et le constructeur par recopie ?
De toutes façons, tant que le destructeur sera appelé sur un objet que j'utilise, j'aurais un problème.

n°1589567
theshockwa​ve
I work at a firm named Koslow
Posté le 20-07-2007 à 17:51:12  profilanswer
 

un opérateur d'affectation ne retourne pas void, et il faut gérer l'affectation d'un élément à lui-même ...

n°1589572
jojoleping​ouin
Posté le 20-07-2007 à 18:06:33  profilanswer
 

theshockwave a écrit :

un opérateur d'affectation ne retourne pas void, et il faut gérer l'affectation d'un élément à lui-même ...


C'est vrai qu'il faut aussi faire gaffe a ca...


Message édité par jojolepingouin le 20-07-2007 à 18:06:51
n°1589904
Taz
bisounours-codeur
Posté le 23-07-2007 à 00:59:36  profilanswer
 

jète. utilise std::vector<double>

mood
Publicité
Posté le 23-07-2007 à 00:59:36  profilanswer
 

n°1590207
KangOl
Profil : pointeur
Posté le 23-07-2007 à 14:45:49  profilanswer
 

theshockwave a écrit :

un opérateur d'affectation ne retourne pas void, et il faut gérer l'affectation d'un élément à lui-même ...


et il prend une référence en parametre :o

n°1590210
theshockwa​ve
I work at a firm named Koslow
Posté le 23-07-2007 à 14:51:30  profilanswer
 

KangOl a écrit :


et il prend une référence en parametre :o


 
ca avait déjà été suggéré :o
 

jojolepingouin a écrit :

Code :
  1. void Article::operator=(const Article & art_orig)


n°1590211
Taz
bisounours-codeur
Posté le 23-07-2007 à 14:52:28  profilanswer
 

beurl le void

n°1590217
theshockwa​ve
I work at a firm named Koslow
Posté le 23-07-2007 à 14:53:54  profilanswer
 

Taz a écrit :

beurl le void


j'vais pas me justifier d'un code que je copie colle et que j'ai déjà critiqué plus haut juste parce que tu n'as pas lu mon message  :kaola:  
 
 
;)

n°1590230
Taz
bisounours-codeur
Posté le 23-07-2007 à 15:10:18  profilanswer
 

putain mais elle me saoule ma touche k !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Surcharge de l'opérateur = + Appel non souhaité à delete

 

Sujets relatifs
appel d'une fonction (execution) qui est definie par un char[]Surcharge d'opérateur sur des structures
requete delete avec un MIN[Résolu] Appeler une fonction avec comme paramètre la fonction d'appel
appel recursif qui ne marche pasAppel d'une procédure dont le nom est contenu dans une variable
Appel d'un web service depuis J2ME : UnsatisfiedLinkError[C++]petite question sur l'opérateur de conversion de classe
[VB.NET/Exchange] Problème : accès refusé à l'appel de la méthode send 
Plus de sujets relatifs à : Surcharge de l'opérateur = + Appel non souhaité à delete


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR