C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Constructeur par copie...
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Fanny Chevalier
Guest





PostPosted: Thu Jul 22, 2004 10:25 am    Post subject: Constructeur par copie... Reply with quote



Bonjour, j'ai quelques petits problemes quant a la bonne facon de liberer
l'espace memoire occupee par mon objet Matrice :


Voici les champs prives de ma classe Matrice...

unsigned int _lines;
unsigned int _columns;
double **_matrix;


mon destructeur :

Matrix::~Matrix()
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;
}


et mon constructeur par copie :
Matrix::Matrix(const Matrix &m)
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;


_lines = m._lines;
_columns = m._columns;

_matrix = new double* [_lines];

for (unsigned int i = 0 ; i < _lines ; i++)
_matrix[i] = new double [_columns];

for (unsigned int i = 0 ; i < _lines ; i++)
for (unsigned int j = 0; j < _columns ; j++)
_matrix[i][j] = (m._matrix)[i][j];
}


On m'a appris a nettoyer avant de recoiper mais ca seg fault...
(meme en mettant if (_matrix[i] != NULL)).
Est-ce que c'est necessaire de faire le nettoyage ou pas?
Si oui, qu'est-ce qui va pas?

Merci par avance,
Fanny

Back to top
David Geldreich
Guest





PostPosted: Thu Jul 22, 2004 10:54 am    Post subject: Re: Constructeur par copie... Reply with quote



Bonjour Fanny,

Fanny Chevalier wrote:
Quote:
et mon constructeur par copie :
Matrix::Matrix(const Matrix &m)
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;


On m'a appris a nettoyer avant de recoiper mais ca seg fault...
(meme en mettant if (_matrix[i] != NULL)).
Est-ce que c'est necessaire de faire le nettoyage ou pas?
Si oui, qu'est-ce qui va pas?

C'est dans l'operator= qu'il faut libérer la mémoire avant de la réallouer.
Dans le cas du constructeur, la mémoire n'a pas encore été allouée (l'objet
n'existait pas avant l'appel du constructeur), donc pas la peine de la libérer.

Bon courage.

Back to top
Falk Tannhäuser
Guest





PostPosted: Thu Jul 22, 2004 11:37 am    Post subject: Re: Constructeur par copie... Reply with quote



Fanny Chevalier wrote:
Quote:

Voici les champs prives de ma classe Matrice...

unsigned int _lines;
unsigned int _columns;
double **_matrix;

mon destructeur :

Matrix::~Matrix()
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;
}

et mon constructeur par copie :
Matrix::Matrix(const Matrix &m)
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;

Non, il n'y a rien à libérer ici ! Un constructeur est
appelé pour créer un nouvel objet dans une zone de mémoire
où il n'en avait pas avant, donc le pointeur '_matrix'
n'a encore jamais été initialisé - en particulier il ne
pointe pas sur un tableau alloué avec 'new[]', et il
n'y a même pas la garantie qu'il vaille NULL, d'où
les "seg fault".

Quote:

_lines = m._lines;
_columns = m._columns;

_matrix = new double* [_lines];

for (unsigned int i = 0 ; i < _lines ; i++)
_matrix[i] = new double [_columns];

for (unsigned int i = 0 ; i < _lines ; i++)
for (unsigned int j = 0; j < _columns ; j++)
_matrix[i][j] = (m._matrix)[i][j];
}

On m'a appris a nettoyer avant de recoiper mais ca seg fault...
(meme en mettant if (_matrix[i] != NULL)).
Est-ce que c'est necessaire de faire le nettoyage ou pas?

Tu confonds peut-être avec l'opérateur d'affectation, genre
Matrix& Matrix::operator=(const Matrix &m)
qui, lui, ne peut être appelé que pour affecter une nouvelle
valeur à un objet déjà existant.

Sinon, tu pourrais te simplifier la vie en utilisant std::vector,
voir std::valarray - ces classes gèrent la mémoire tout seul ...

Falk

Back to top
drkm
Guest





PostPosted: Thu Jul 22, 2004 12:50 pm    Post subject: Re: Constructeur par copie... Reply with quote

Fanny Chevalier <chevalie (AT) labri (DOT) fr> writes:

[...]

Quote:
On m'a appris a nettoyer avant de recoiper mais ca seg fault...

Où ?

Quote:
(meme en mettant if (_matrix[i] != NULL)).

Ce n'est effectivement pas nécessaire. « delete [] 0 » est bien
défini et ne fait rien. Mais si tu n'es pas certaine que la matrice a
bien été allouée avant de la désallouer, tu as un problème. La boucle
for déréférence le pointeur _matrix, en faisant _matrix[ i ]. Il faut
alors tester s'il faut ou non désallouer *avant* le parcours de
_matrix.

En passant, les noms commençant par un '_' sont pour beaucoup
interdits. Les règles sont plus précises que cela, mais une bonne
pratique est de ne jamais utiliser de tels identificateurs. Sauf bien
sûr si tu implémente la bibliothèque standard. Cfr. les archives du
groupe.

Une autre bonne pratique, bien que je pense que tout le monde ne
s'accorde pas dessus, est de mettre un pointeur désalloué à 0. Cela
sert en quelque sorte de marqueur pour dire « je ne suis pas alloué ».
J'ai déjà vu des choses comme :

template < typename T >
void myDelete( T * & p ) {
delete p ;
p = 0 ;
}

Quote:
Est-ce que c'est necessaire de faire le nettoyage ou pas?

Ca dépend. Veux-tu éviter les fuites mémoire ?-)

Quote:
Si oui, qu'est-ce qui va pas?

A priori, je ne vois que le problème de déréférencement de _matrix
lors de la désallocation, alors qu'elle n'a pas été allouée. Ceci
devrait résoudre le problème :

Matrix::~Matrix() {
if ( _matrix ) {
for ( int i = 0 ; i < _lines ; ++ i ) {
delete [] _matrix[ i ] ;
}
delete [] _matrix ;
_matrix = 0 ;
}
}

Comme cette opération est commune au destructeur et au constructeur
de copie, j'en ferais une fonction membre privée :

bool Matrix::cleanup() {
if ( _matrix ) {
for ( int i = 0 ; i < _lines ; ++ i ) {
delete [] _matrix[ i ] ;
}
delete [] _matrix ;
_matrix = 0 ;
return true ;
}
else {
return false ;
}
}

Matrix::~Matrix() {
cleanup() ;
}

Matrix::Matrix( Matrix const & rhs ) {
cleanup() ;
// ...
}

Enfin, pour ce genre de choses, je trouve plus simple, et sans doute
plus efficace, d'utiliser une seule allocation, et de calculer le
décalage d'après les indices. Quelque chose comme :

Matrix::Matrix( Matrix const & rhs )
{
int num_of_cells = rhs._lines * rhs._columns ;

if ( ! _matrix || _lines * _columns != num_of_cells ) {
double * new_matrix = new double[ num_of_cells ] ;
delete [] _matrix ;
_matrix = new_matrix ;
_lines = rhs._lines ;
_columns = rhs._columns ;
}

for ( int i = 0 ; i < num_of_cells ; ++ i ) {
_matrix[ i ] = rhs._matrix[ i ] ;
}
}

Matrix::~Matrix()
{
delete [] _matrix ;
_matrix = 0 ;
}

double &
Matrix::at( int l , int c )
{
assert( l >= 0 && l < _lines && c >= 0 && c < _columns ) ;
return _matrix[ l * _columns + c ] ;
}

L'utilisation de `new_matrix' permet d'éviter de modifier l'objet en
cas d'exception lancée par new. Bien que je ne vois pas si cela peut
être utile ...

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Back to top
drkm
Guest





PostPosted: Thu Jul 22, 2004 1:00 pm    Post subject: Re: Constructeur par copie... Reply with quote


Hum. Évidemment, comme l'a fait remarquer Falk, le constructeur de
copie est un constructeur, donc rien n'a encore pu être alloué. Il
faut vraiment que je me réveille :-(

Matrix::Matrix( Matrix const & rhs )
: _lines( rhs._lines )
, _columns( rhs._columns )
, _matrix( new double[ _lines * _columns ] )
{
for ( int i = 0 ; i < num_of_cells ; ++ i ) {
_matrix[ i ] = rhs._matrix[ i ] ;
}
}

Désolé pour cette erreur monu-mentale.

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
Back to top
drkm
Guest





PostPosted: Thu Jul 22, 2004 1:06 pm    Post subject: Re: Constructeur par copie... Reply with quote

drkm <usenet.fclcxx (AT) fgeorges (DOT) org> writes:

Quote:
for ( int i = 0 ; i < num_of_cells ; ++ i ) {

for ( int i = 0 ; i < _lines * _columns ; ++ i ) {

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Back to top
Arnaud Meurgues
Guest





PostPosted: Thu Jul 22, 2004 1:15 pm    Post subject: Re: Constructeur par copie... Reply with quote

drkm wrote:

Quote:
Matrix::~Matrix() {
if ( _matrix ) {
for ( int i = 0 ; i < _lines ; ++ i ) {
delete [] _matrix[ i ] ;
}
delete [] _matrix ;
_matrix = 0 ;

Dans un destructeur, c'est pas forcément très utile, non plus. Ça peut
permettre de rendre plus visible l'utilisation d'un objet déjà détruit,
mais il vaudrait mieux s'assurer qu'on utilise pas d'objet déjà détruit.

--
Arnaud
(Supprimez les geneurs pour me répondre)

Back to top
Bertrand Motuelle
Guest





PostPosted: Thu Jul 22, 2004 2:01 pm    Post subject: Re: Constructeur par copie... Reply with quote

Fanny Chevalier <chevalie (AT) labri (DOT) fr> wrote

Quote:
Bonjour, j'ai quelques petits problemes quant a la bonne facon de liberer
l'espace memoire occupee par mon objet Matrice :

Voici les champs prives de ma classe Matrice...

unsigned int _lines;
unsigned int _columns;
double **_matrix;


mon destructeur :

Matrix::~Matrix()
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;
}


et mon constructeur par copie :
Matrix::Matrix(const Matrix &m)
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;


_lines = m._lines;
_columns = m._columns;

_matrix = new double* [_lines];

for (unsigned int i = 0 ; i < _lines ; i++)
_matrix[i] = new double [_columns];

for (unsigned int i = 0 ; i < _lines ; i++)
for (unsigned int j = 0; j < _columns ; j++)
_matrix[i][j] = (m._matrix)[i][j];
}


On m'a appris a nettoyer avant de recoiper mais ca seg fault...
(meme en mettant if (_matrix[i] != NULL)).
Est-ce que c'est necessaire de faire le nettoyage ou pas?
Si oui, qu'est-ce qui va pas?

Le nettoyage est nécessaire dans un opérateur d'affectation.
Mais que veux-tu nettoyer dans un objet en construction ?

Quote:
Matrix::Matrix(const Matrix &m)
{
for (unsigned int i = 0 ; i < _lines ; i++)
delete [] _matrix[i];
delete [] _matrix;

Ici tu fais des delete sur des pointeurs non-initialisés (et _lines a
une valeur indeterminée). Ce code est inutile.

Bertrand.

Back to top
drkm
Guest





PostPosted: Thu Jul 22, 2004 2:32 pm    Post subject: Re: Constructeur par copie... Reply with quote

Arnaud Meurgues <arnaud (AT) meurgues (DOT) non.fr.invalid> writes:

Quote:
drkm wrote:

Matrix::~Matrix() {
if ( _matrix ) {
for ( int i = 0 ; i < _lines ; ++ i ) {
delete [] _matrix[ i ] ;
}
delete [] _matrix ;
_matrix = 0 ;

Dans un destructeur, c'est pas forcément très utile, non plus. Ça peut
permettre de rendre plus visible l'utilisation d'un objet déjà
détruit, mais il vaudrait mieux s'assurer qu'on utilise pas d'objet
déjà détruit.

La première fois que j'ai vu une telle chose, il me semble que
c'était dans un article de Sutter (mais là, je ne suis pas sûr). Cela
m'avait étonné, au premier abord. Mais je trouve finalement que pour
un coût minime, cela permet parfois de se rendre compte, au moyen
d'une sortie de debug ou d'un debuger, que l'on accède à un pointeur
non alloué. Je pense que c'est intéressant justement pour provoquer
une faute de segmentation si l'on essaie de déréférencer ce pointeur.
J'imagine que :

int * p = new int ;
delete p ;
* p = 0 ;

passerait sans problème à l'exécution dans beaucoup de cas (outre
l'avertissement à la compilation de tout compilateur digne de ce nom,
j'imagine). Mais pas :

int * p = new int ;
delete p ;
p = 0 ;
* p = 0 ;

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Back to top
Loïc Joly
Guest





PostPosted: Thu Jul 22, 2004 6:12 pm    Post subject: Re: Constructeur par copie... Reply with quote

drkm wrote:

Quote:
Désolé pour cette erreur monu-mentale.

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Et avec ce genre d'erreurs, tu espères en trouver ? O;p

--
Loïc


Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Jul 22, 2004 6:24 pm    Post subject: Re: Constructeur par copie... Reply with quote

On Thu, 22 Jul 2004 15:06:20 +0200, drkm <usenet.fclcxx (AT) fgeorges (DOT) org>:

Quote:
--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Le projet sur lequel je travaillerai dans le
cadre de ce stage doit
comporter de l'analyse et de la programmation.

Analyse de la machine à café et programmation d'icelle pour que le
café soit prêt quand tout le monde arrive le matin, ça te convient ?


--
;-)

Back to top
drkm
Guest





PostPosted: Thu Jul 22, 2004 9:01 pm    Post subject: Re: Constructeur par copie... Reply with quote

Fabien LE LEZ <gramster (AT) gramster (DOT) com> writes:

Quote:
On Thu, 22 Jul 2004 15:06:20 +0200, drkm <usenet.fclcxx (AT) fgeorges (DOT) org>:

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Le projet sur lequel je travaillerai dans le
cadre de ce stage doit
comporter de l'analyse et de la programmation.

Analyse de la machine à café et programmation d'icelle pour que le
café soit prêt quand tout le monde arrive le matin, ça te convient ?

Je tiens à préciser que le « doit comporter de l'analyse et de la
programmation » n'est pas de moi, mais est la seule information que
j'ai pu obtenir de la responsable des stages pour l'Institut.

Mais ta proposition m'intéresse, oui. Je signe où ?

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Back to top
drkm
Guest





PostPosted: Thu Jul 22, 2004 9:02 pm    Post subject: Re: Constructeur par copie... Reply with quote

Loïc Joly <loic.actarus.joly (AT) wanadoo (DOT) fr> writes:

Quote:
drkm wrote:

Désolé pour cette erreur monu-mentale.
--drkm, en recherche d'un stage :
http://www.fgeorges.org/ipl/stage.html

Et avec ce genre d'erreurs, tu espères en trouver ? O;p

Pourquoi, l'honnêteté ne paye pas ?-)

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html

Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Jul 22, 2004 9:05 pm    Post subject: Re: Constructeur par copie... Reply with quote

On Thu, 22 Jul 2004 23:01:13 +0200, drkm <usenet.fclcxx (AT) fgeorges (DOT) org>:

Quote:
Je tiens à préciser que le « doit comporter de l'analyse et de la
programmation » n'est pas de moi

Au fait, "programmation", j'ai une vague idée, mais "analyse", ça veut
dire quoi exactement ?


--
;-)

Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Jul 22, 2004 9:06 pm    Post subject: Re: Constructeur par copie... Reply with quote

On Thu, 22 Jul 2004 23:01:13 +0200, drkm <usenet.fclcxx (AT) fgeorges (DOT) org>:

Quote:
où ?

Ben... en Bretagne, i.e. à l'autre bout du monde.

De toutes façons je plaisantais, je ne supporte pas le café.

--
;-)

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.