Acquis de conscience en c++ ? [Help] - Programmation
Marsh Posté le 17-12-2001 à 08:48:47
hello,
quand tu fais une allocation dynamique, c'est TOUJOURS à toi de faire la désallocation (sauf pour certaines API très particulières dont on ne parlera pas ici).
Les détruire explicitement dans le detructeur me semble une bonne idée Personnellement, quand je fait une désallocation, je mets TOUJOURS ensuite le pointeur à NULL. Et donc dans le destructeur, tu peux faire un
if(ptr != NULL)
{
delete [] ptr;
ptr = NULL;
}
A priori cela ne coute pas grabd chose.
Par contre attention, car si tu utilises ce tableau dans une autre classe et que la classe qui l'a crée, il peut y avoir un soucis Attention donc de ne pas utiliser le tableau une fois qu'il a été détruit
a+
Marsh Posté le 17-12-2001 à 09:24:01
SoWhatIn22 a écrit a écrit : hello, quand tu fais une allocation dynamique, c'est TOUJOURS à toi de faire la désallocation (sauf pour certaines API très particulières dont on ne parlera pas ici). Les détruire explicitement dans le detructeur me semble une bonne idée Personnellement, quand je fait une désallocation, je mets TOUJOURS ensuite le pointeur à NULL. Et donc dans le destructeur, tu peux faire un if(ptr != NULL) { delete [] ptr; ptr = NULL; } A priori cela ne coute pas grabd chose. Par contre attention, car si tu utilises ce tableau dans une autre classe et que la classe qui l'a crée, il peut y avoir un soucis Attention donc de ne pas utiliser le tableau une fois qu'il a été détruit a+ |
Bah, si le programme est bien fait, ce tableau ne doit être accessible par l'intermédiaire de l'instance qui contient le tableau. Si le tableau est désalloué dans le destructeur de l'instance qui contient le tableau, impossible de tenter d'utiliser le tableau du moment qu'il à été détruit ! c qd même génial l'objet !
Marsh Posté le 17-12-2001 à 11:02:10
Le destructeur n'est appele que dans les cas suivants:
- tu arrives a la fin du scope de ton objet
(alloue sur la pile => destruction automatique en fin
de procedure, objet membre =>
destruction automatique a la destruction de l'objet
qui le contient, allocation globale => destruction a la sortie de l'application)
- tu appelles delete sur cet objet (si celui-ci a
ete prealablement alloue par new).
Quand je dis "objet membre" cela exclut bien evidemment
les pointeurs et les references. Dans ce cas, il faut definir
QUI doit detruire les objets pointes ou references. C'est a toi de definir ta convention, mais il faut s'y tenir strictement parce que chaque objet ne peut etre detruit qu'une seule fois (sinon plantage!).
A+
LEGREG
Marsh Posté le 17-12-2001 à 14:16:48
merci pour tout ca, mais cela n'arrange pas mon affaire, car le fait de detruire une objet membre ds le destructeur , voir meme ailleurs pose des problemes (ERROR / DAMAGE ...)
je vous pose ma class
class Ligne
{
private :
short* ligne;
...
public :
Ligne();
void Saisir(int taille);
...
~Ligne();
};
quand je saisis un objet de Ligne je fais a l'interieur un
ligne = new short [taille] ;
donc je renseigne la donnée membre ligne
mais si je met ds le destructeur ou meme ailleur un delete [] ligne
ou meme un free(ligne) (qUI n'appelle pas le destructeur)
j'ai un gros message d'erreur
quoi faire pour dessalouer cette !!!! de memoire ?
Marsh Posté le 17-12-2001 à 14:22:35
un truc possible : ton membre ligne appartient à la classe Ligne ... peut être qu'il aime pas trop ça !
Marsh Posté le 17-12-2001 à 14:36:19
ben logiquement non car
le tableau de short ligne est en minuscule
et la classe Ligne est en majuscule
(je parle du "L" )
donc il s'agit de 2 chose differente
Marsh Posté le 17-12-2001 à 14:37:11
ok je viens de capter
oui c ca et je pense (suis presque sur) que le probleme vient de la
et je cherche en faite la technique pour contourner ce prob
Marsh Posté le 17-12-2001 à 14:43:44
...bah, changer le nom de ton membre !!
d'ailleur normalement, on préfixe les attributs de classe par m_, puis une lettre qui indique le type du membre. Si ton prog était écrit selon les normes, ça donnerai
m_lpsLigne.
lp signifiant qu'il s'agit d'un pointeur
Marsh Posté le 17-12-2001 à 14:44:00
Rob Roy a écrit a écrit : merci pour tout ca, mais cela n'arrange pas mon affaire, car le fait de detruire une objet membre ds le destructeur , voir meme ailleurs pose des problemes (ERROR / DAMAGE ...) je vous pose ma class class Ligne { private : short* ligne; ... public : Ligne(); void Saisir(int taille); ... ~Ligne(); }; quand je saisis un objet de Ligne je fais a l'interieur un ligne = new short [taille] ; donc je renseigne la donnée membre ligne mais si je met ds le destructeur ou meme ailleur un delete [] ligne ou meme un free(ligne) (qUI n'appelle pas le destructeur) j'ai un gros message d'erreur quoi faire pour dessalouer cette !!!! de memoire ? |
deja tu commences par ne pas utiliser free sur un objet
alloue par new! new ce n'est pas un malloc.
Ensuite es-tu sur d'appeler toujours ton destructeur
sur un membre initialise?
(par exemple tu peux l'initialiser a NULL
tant qu'il n'est pas rempli et
faire le test de SoWhatIn dans le destructeur)
A+
LEGREG
Marsh Posté le 17-12-2001 à 14:50:27
oui j'en suis certain !
mon main pour le test est
Ligne P;
P.Saisir(2);
P.Afficher();
et c tout
et il trouve le moyen de me foutre une erreur qund je fais un delete [] ligne ds le constructeur !
Marsh Posté le 17-12-2001 à 14:54:51
essaie de poster le code complet du truc
ou un exemple simple qui plante
j'crois qu'il nous manque du materiel
pour juger..
LEGREG
Marsh Posté le 17-12-2001 à 15:08:30
El_Gringo a écrit a écrit : ...bah, changer le nom de ton membre !! d'ailleur normalement, on préfixe les attributs de classe par m_, puis une lettre qui indique le type du membre. Si ton prog était écrit selon les normes, ça donnerai m_lpsLigne. lp signifiant qu'il s'agit d'un pointeur |
non je sais tout ca mais comme mon binome est un nb de chez nb en c++ (ce qui ne veut pas dire que je soit un boss) ds un premier tps on avait pris des termes tout simple.Mais cela ne change rien de tte facon !
enfin bon voila mon code simplifié de tout ce qui n'est pas important
class CLigne
{
private :
short* m_lpsLigne;
...
public :
CLigne();
void Saisir(int taille);
...
1 ~CLigne();
};
void CLigne::Saisir(int taille)
{
m_lpsLigne = new short [taille] ;
for (int i=1;i<=taille;i++)
{
cin >> m_lpsLigne[i];
}
}
CLigne::~CLigne()
{
delete [] m_lpsLigne;
}
edit : et mon main n'est qu'un simple
CLigne L;
L.Saisir(3); et c tout !!!
[edtdd]--Message édité par Rob Roy--[/edtdd]
Marsh Posté le 17-12-2001 à 15:13:20
Rob Roy a écrit a écrit : void CLigne::Saisir(int taille) { m_lpsLigne = new short [taille] ; for (int i=1;i<=taille;i++) { cin >> m_lpsLigne[i]; } } |
attention un tableau en C/C++
commence a 0 et finit a taille-1.
[OT]
Je ne sais pas si c'est plus logique qu'une autre
numerotation et je ne veux pas le savoir mais
c'est comme ca
[/OT]
LEGREG
Marsh Posté le 17-12-2001 à 15:37:16
merci pour ce ptit detail que j'avais oublié
nmais ca marche pas mieux, car en fait meme si mes tableaux etait plus grand que la normal (...) l'espace etait quand meme alloué et le probleme reste le meme !
Marsh Posté le 17-12-2001 à 15:39:28
j'crois qu'il faut que tu rajoutes encore
un bout de ton programme..
LEGREG
Marsh Posté le 17-12-2001 à 15:48:17
nop ca suffit car le prog plante quand mon main a =>
void main()
{
CLigne P;
P.Saisir(2);
}
ridicule quoi
Marsh Posté le 17-12-2001 à 16:04:52
ben tu as l'air de savoir la ou ca plante
malheureusement
je crois qu'il nous manque encore du code
=> pourquoi ne pas nous donner au moins
toute l'implantation de CLine?
J'imagine egalement que le "1"devant la declaration de "~CLigne()"
est une erreur de copier-coller..
LEGREG
Marsh Posté le 17-12-2001 à 16:08:41
class CLigne
{
friend class CMatrice;
private :
short* m_lpsLigne;
bool m_bOnly0;
public :
CLigne();
void Saisir(int taille);
void Afficher();
void Ajouter(CLigne L);
~CLigne();
};
Marsh Posté le 17-12-2001 à 16:10:40
en passant ya t'il un moyen d'empecher l'utilisateur de taper autre chose qu'un int ou un short dans un cin ou encore un moyen de tester les valeur que l'utilisateur rentre ?
Marsh Posté le 17-12-2001 à 16:24:45
Code :
|
Sinon, je veux bien jouer au puzzle
mais ca va etre dur de t'aider
LEGREG
Marsh Posté le 17-12-2001 à 16:36:14
merci pour qui ya en haut
euh j'ai tout mis
je remet tout ds un post if y like
class CLigne
{
friend class CMatrice;
private :
short* m_lpsLigne;
bool m_bOnly0;
public :
CLigne();
void Saisir(int taille);
void Afficher();
void Ajouter(CLigne L);
~CLigne();
};
CLigne::CLigne()
{
m_lpsLigne=NULL;
m_bOnly0=true;
}
void CLigne::Saisir(int taille)
{
m_lpsLigne = new short [taille-1] ;
for (int i=0;i<=taille-1;i++)
{
cin >> m_lpsLigne[i];
}
}
CLigne::~CLigne()
{
delete [] m_lpsLigne;
}
void main()
{
CLigne P;
P.Saisir(2);
}
Marsh Posté le 17-12-2001 à 17:13:15
quand je disais qu'un tableau ca va de 0 a taille-1
taille c'est la taille du tableau
et il faut donc faire un
tableau = new short[taille]; <-- cree un tableau a taille element
numerotes de 0 a taille-1
LEGREG
Marsh Posté le 17-12-2001 à 17:23:37
le std c'est juste pour dire que cin et cout
sont definis dans l'espace de nom std
Tu peux eviter de preciser l'espace de nom
a chaque fois en mettant une fois pour toute
au debut de ton fichier
using namespace std;
par contre je ne vois pas ou tu as mis
ton
#include <iostream>
c'est le fichier qui contient les definitions
de cin et cout
A+
LEGREG
Marsh Posté le 17-12-2001 à 02:26:27
je créé une classe composé ayant comme donnée membre un tableau dynamique et d'autres trucs
a chaque fois que je créé un objet de cette classe je 'alloue (new ...) donc ce tableau dynamique pour le reutiliser plus tard ds une autre classe.
Ma question concerne en realité le destruceur. Dois-je desallouer par delete les tableaux que je créé, a la fin de mon programme, ou le destructeur se charge t'il de le faire pour moi.
Sinon comment faire ?
Merchi
++