PDA

View Full Version : [C++] Strano problema con deallocazione memoria.


alessandrom
07-02-2012, 18:33
Ciao a tutti,

sto realizzando un programma per rappresentare le matrici.
Il programma funziona molto bene tranne quando uso l'operator= per copiare una matrice già esistente.

Se eseguo con valgrind mi dice questo:
==3283== Invalid read of size 8
==3283== at 0x4026DA: SparseMatrix<int>::clearAll() (SparseMatrix.h:285)
==3283== by 0x401D2F: SparseMatrix<int>::~SparseMatrix() (SparseMatrix.h:561)
==3283== by 0x401B61: main (main.cpp:67)
==3283== Address 0x596f5b8 is 8 bytes inside a block of size 24 free'd
==3283== at 0x4C27FF2: operator delete(void*) (vg_replace_malloc.c:387)
==3283== by 0x402713: SparseMatrix<int>::clearAll() (SparseMatrix.h:292)
==3283== by 0x401D2F: SparseMatrix<int>::~SparseMatrix() (SparseMatrix.h:561)
==3283== by 0x401B52: main (main.cpp:88)
==3283==
==3283== Invalid read of size 8
==3283== at 0x4026FC: SparseMatrix<int>::clearAll() (SparseMatrix.h:291)
==3283== by 0x401D2F: SparseMatrix<int>::~SparseMatrix() (SparseMatrix.h:561)
==3283== by 0x401B61: main (main.cpp:67)
==3283== Address 0x596f5c0 is 16 bytes inside a block of size 24 free'd
==3283== at 0x4C27FF2: operator delete(void*) (vg_replace_malloc.c:387)
==3283== by 0x402713: SparseMatrix<int>::clearAll() (SparseMatrix.h:292)
==3283== by 0x401D2F: SparseMatrix<int>::~SparseMatrix() (SparseMatrix.h:561)
==3283== by 0x401B52: main (main.cpp:88)
==3283==
==3283== Invalid free() / delete / delete[]
==3283== at 0x4C27FF2: operator delete(void*) (vg_replace_malloc.c:387)
==3283== by 0x402713: SparseMatrix<int>::clearAll() (SparseMatrix.h:292)
==3283== by 0x401D2F: SparseMatrix<int>::~SparseMatrix() (SparseMatrix.h:561)
==3283== by 0x401B61: main (main.cpp:67)
==3283== Address 0x596f5b0 is 0 bytes inside a block of size 24 free'd
==3283== at 0x4C27FF2: operator delete(void*) (vg_replace_malloc.c:387)
==3283== by 0x402713: SparseMatrix<int>::clearAll() (SparseMatrix.h:292)
==3283== by 0x401D2F: SparseMatrix<int>::~SparseMatrix() (SparseMatrix.h:561)
==3283== by 0x401B52: main (main.cpp:88)
==3283==
==3283==
==3283== HEAP SUMMARY:
==3283== in use at exit: 0 bytes in 0 blocks
==3283== total heap usage: 48 allocs, 49 frees, 672 bytes allocated
==3283==
==3283== All heap blocks were freed -- no leaks are possible
==3283==
==3283== For counts of detected and suppressed errors, rerun with: -v
==3283== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 4 from 4)


Ho capito che l'errore è nella funzione clearAll invocata nel distruttore, ma non riesco a capire quale sia il problema.

Questo è il codice di clearAll:
void clearAll(){
if(matrix==NULL) return;
while(matrix!=NULL){
while(matrix->values!=NULL){
mcol *aux=matrix->values;
matrix->values=matrix->values->next;
delete aux;
}
mrow *aux2=matrix;
matrix=matrix->next;
delete aux2;
}
matrix=NULL;
}

Cait Sith
07-02-2012, 22:27
scusa, visto che il valgrind ti dice esattamente dov'è il problema non potresti postare i numeri di riga del codice?

comunque anche se i nodi vengono al pettine nel clearAll, è possibile che l'errore sia in una mancata inizializzazione di un elemento da qualche altra parte

alessandrom
07-02-2012, 22:53
scusa, visto che il valgrind ti dice esattamente dov'è il problema non potresti postare i numeri di riga del codice?

comunque anche se i nodi vengono al pettine nel clearAll, è possibile che l'errore sia in una mancata inizializzazione di un elemento da qualche altra parte

La riga incriminata è il secondo delete, delete aux2.

E il problema è un altro, che ho "risolto", ovvero l'operatore di assegnamento.
Così funziona:
SparseMatrix& operator=(const SparseMatrix& sm){
rows=sm.getRows();
cols=sm.getCols();
def=sm.getDef();
msize=sm.getSize();
clearAll();
matrix=NULL;
copyAll(sm.getMatrix());
return *this;
}

Se però lo volessi fare templato per poter copiare anche matrici di tipi diversi compatibili mi da quell'errore.
Uso lo stesso codice templato nel copy constructor e là non da errori:
(T è il tipo di cui sparsematrix è contenitore, è definito con la classe)
template<typename T1>
SparseMatrix<T>( SparseMatrix<T1>& sm){
rows=sm.getRows();
cols=sm.getCols();
def=sm.getDef();
matrix=NULL;
msize=0;
copyAll<T1>(sm.getMatrix());
}