PDA

Visualizza la versione completa : [C++] Errore di allocazione nella creazione di una classe


RooccoXXI
15-08-2012, 22:11
Ciao a tutti. Ho un'errore di allocazione in una classe che sto creando, che rappresenta delle matrici.

Questa é l'istruzione che da problemi:

cout << m1 + m4 + m4 + m4 << endl;

Viene quindi chiamata la funzione operator+:

template <typename T>
Matrix<T> Matrix<T>::operator+(const Matrix<T>& m) const
{
if( (row != m.row) or (col != m.col) )
{
throw std::range_error("");
}

Matrix<T> tmp(*this);

for(int i(0); i < row; i++)
{
for(int j(0); j < col; j++)
{
tmp.data[i][j] += m.data[i][j];
}
}

return std::move(tmp);
}

Penso che l'operatore sia giusto e che quindi l'errore si trovi nell'invocazione del costruttore di copia:


template <typename T>
Matrix<T>::Matrix(const Matrix<T>& m)
{
copy(m);
}

E quindi nella funzione copy:


template <typename T>
void Matrix<T>::copy(const Matrix<T>& m)
{
row = m.row;
col = m.col;

cancel();

data = new T*[row];
for(int i(0); i < row; i++)
{
data[i] = new T[col];
}

for(int i(0); i < row; i++)
{
for(int j(0); j < col; j++)
{
data[i][j] = m.data[i][j];
}
}
}

template <typename T>
void Matrix<T>::cancel()
{
for(int i(0); i < row; i++)
{
delete data[i];
}

delete data;
data = nullptr;
}

Grazie,
R.

Ps: Ho già aperto una discussione riguardante quella classe ma trovo più corretto (soprattutto per chi utilizza il tasto "cerca") aprire una nuova discussione per questo errore specifico...

RooccoXXI
15-08-2012, 22:15
Forse ho capito... L'errore é che viene chiamata la funzione cancel() dal costruttore di copia, quando ancora non ho allocato nessuna memoria... In questo caso devo quindi differenziare il comportamento del costruttore di copia e dell'operatore = ? (Nel primo caso non cancello i vecchi dati perché proprio non ve ne sono, mentre nel caso dell'operatore cancello i vecchi dati, rialloco la memoria e infine salvo i nuovi dati).

Qualche esperto può confermare (o correggermi se sbaglio ancora)?

Grazie.

:cry:

RooccoXXI
16-08-2012, 02:01
L'errore l'ho risolto estraendo la funzione cancel() da copy() e chiamandola solo nell'operatore =.

Ora però ho un problema di segmentation fault sulla seguente moltiplicazione di matrici...


template <typename T>
Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& m)
{
if( col != m.row ) // Verifica se la moltiplicazione é definita
{
throw std::range_error("");
}

Matrix<T> tmp(*this); // Salva la matrice corrente in una temporanea

col = m.col; // Setta le colonne della matrice per contenete la matrice risultante (le linee rimangono inalterate)
cancel(); // Elimina i dati contenuti precedentemente
data = new T*[row]; // Rialloca la memoria con la nuova dimensione
for(int i(0); i < row; i++)
{
data[i] = new T[col];
}

for(size_t i(0); i < row; i++) // Scorre sulle line
{
for(size_t j(0); j < col; j++) // Scorre sulle colonne
{
for(size_t k(0); k < m.col; k++ ) // Somma i temrini
{
data[i][j] += tmp.data[i][k] * m.data[k][j];
}
}
}

return *this; // Ritorna la matrice corrente
}

Qualcuno sa dirmi dove sbaglio?

Grazie!

RooccoXXI
16-08-2012, 02:05
Un piccolo errore credo di averlo trovato: nel secondo ciclo for utilizzo "col", ma ormai é diventato "m.col"... Ho cambiato con "m.row" che é rimasto invariato ed é uguale al vecchio "col".

Il segmentation fault però rimane comunque... :cry:

Loading