Pb de destructeur [Résolu]

Signaler
Messages postés
80
Date d'inscription
lundi 18 février 2002
Statut
Membre
Dernière intervention
12 janvier 2007
-
Messages postés
80
Date d'inscription
lundi 18 février 2002
Statut
Membre
Dernière intervention
12 janvier 2007
-
Salut a tous,

j'ai un pb de destructeur que je n'arrive pas a resoudre:

Mon constructeur:

template < class H >
inline
Matrix< H >::Matrix( int row, int column )
: _row (row),
_column (column)
{
_data = new H*[_row];
for (int i = 0; i < _row; i++)
_data[i] = new H[_column];
}


et voici le destructeur:

template < class H >
inline
Matrix< H >::~Matrix()
{
for (int i = 0; i < _row; i++)
delete[] _data[i];
delete[] _data;
_data = NULL;
}



Mon problème est le suivant:
je crée mes objets sans problèmes, avec initialisation, application de méthodes, mais dès qu'il faut detruire l'objet, le prog plante.

Après avoir regardé ce qu'il se passait avec le debugger, il se trouve que c'est la libération de mémoire qui plante avec:
delete[] _data[i];

Je ne comprends pas pourquoi ca ne fonctionne pas...
Est-ce que ca pourrais venir du fait que ce soit en template???

7 réponses

Messages postés
80
Date d'inscription
lundi 18 février 2002
Statut
Membre
Dernière intervention
12 janvier 2007

Ca y est, le problème est résolu.

Je tiens a te remercier cosmobob.

Le problème se résoud en modifiant le constructeur par copie de la facon suivante:


template < class H >
inline Matrix< H >::Matrix( const Matrix< H >& A )
{
_row = A._row;
_column = A._column;

_data = new H*[_row];
for (int i = 0; i < _row; i++)
_data[i] = new H[_column];

for (int i = 0; i < _row; i++)
for (int j = 0; j < _column; j++)
_data[i][j] = A._data[i][j];
}

Le problème étant en effet que deux objets avaient la même adresse pour le tableau de data...
Messages postés
80
Date d'inscription
lundi 18 février 2002
Statut
Membre
Dernière intervention
12 janvier 2007

De façons plus lisible (toute mes excuses):

Salut a tous,j'ai un pb de destructeur que je n'arrive pas a resoudre:

Mon constructeur:

template < class H >
inline
Matrix::Matrix( int row, int column )
: _row (row),
_column (column)
{
_data = new H*[_row];
for (int i = 0; i < _row; i++)
_data[i] = new H[_column];
}

et voici le destructeur:

template <class H >
inline
Matrix::~Matrix()
{
for (int i = 0; i < _row; i++)
delete[] _data[i];
delete[] _data; _data = NULL;
}


Mon problème est le suivant:
je crée mes objets sans problèmes, avec initialisation, application de méthodes, mais dès qu'il faut detruire l'objet, le prog plante. Après avoir regardé ce qu'il se passait avec le debugger, il se trouve que c'est la libération de mémoire qui plante avec:

delete[] _data[i];

Je ne comprends pas pourquoi ca ne fonctionne pas...
Est-ce que ca pourrais venir du fait que ce soit en template???
Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
salut,

as tu défini proprement un constructeur de copie par défaut et un operateur d'affectation ?

Matrix(const Matrix& b);

Matrix& operator = (const Matrix& b);



dans le cas contraire, ca va planter dans le destructeur si par
exemple, tu fais une affectation entre deux matrices ou que tu passes
une matrice comme parametre d'une fonction ou bien que tu fais un
return d'une matrice.

la raison est que tu aurais deux matrices dont le champ _data pointe
vers la meme zone memoire (si tu n'as pas défini le constructeur de
copie ou l'operateur =, par défaut l'affectation ou la copie se fait en
recopiant betement les champs de ta classe), et que cette zone memoire
est alors détruite deux fois (et plantage la deuxieme fois).

tu dois par exemple définir l'affectation entre deux matrices de cette maniere:

template < class H >

inline Matrix& operator = (const Matrix& b)

{

for (int i = 0; i < _row; i++)

delete[] _data[i];

delete[] _data; _data = NULL;



_row = b._row;

_column = b._column;



_data = new H*[_row];

for (int i = 0; i < _row; i++)

{

_data[i] = new H[_column];

*(_data[i]) = *(b._data[i]);

}

return *this;

}



(et pareil pour le constructeur par copie)



sinon, c'est sur que ca n'a rien à voir avec les template



a+
Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
enfin c'est ca l'idée; la je me rend compte que je suis allé vite et
qu'il faut faire une boucle aussi pour recopier toute la colonne de b
dans le _data[i] de this (dans ce que je t'ai montré, ya que la
premiere case qui est recopiée :)



sinon, connais tu le type vector ? ca t'éviterait des soucis :)

une matrice est un vecteur de vecteurs, tu peux utiliser vector<vector<H>>.



a+
Messages postés
80
Date d'inscription
lundi 18 février 2002
Statut
Membre
Dernière intervention
12 janvier 2007

En effet, j'ai pense a creer le constructeur de copie et l'operateur d'affectation:

template < class H >
inline Matrix< H >::Matrix( const Matrix< H >& A )
{
*this = A;
}



template < class H >
inline
Matrix< H >& Matrix< H >::operator = ( const Matrix< H >& A )
{
if ( _row != A._row || _column != A._column )
{
// Resize de la matrice cible
for (int i = 0; i < _row; i++)
delete[] _data[i];
delete[] _data;

_row = A._row;
_column = A._column;

_data = new H*[_row];
for (int i = 0; i < _row; i++)
_data[i] = new H[_column];
}

for (int i = 0; i < _row; i++)
for (int j = 0; j < _column; j++)
_data[i][j] = A._data[i][j];

return *this;
}


Mais peut etre est-ce la le pb...
Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
template < class H >

inline Matrix< H >::Matrix( const Matrix< H >& A )

{

_row = 0;

_column = 0;

_data = 0;

*this = A;

}



peut etre ca ira mieux apres?
Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
quand tu debugges, affiche l'adresse de chaque zone mémoire libérée, il
y a 90% de chance que le plantage soit du a une zone liberée deux fois.



a+