cpp – valgrind – Lettura non valida della dimensione 8

Sto diventando pazzo a capire che errore valgrind. Ho una class template chiamata Matrix che ha alcuni operatori sovraccaricati ecc … per fare alcune operazioni matematiche. Le matrici vengono utilizzate all’interno di una class chiamata ExtendedKalmanFilter.

Ecco la traccia del valgrind:

==3352== Invalid read of size 8 ==3352== at 0x804CC8F: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:285) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== Address 0x6a8b3c0 is 0 bytes after a block of size 48 alloc'd ==3352== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3352== by 0x804C986: BOViL::math::Matrix::operator=(BOViL::math::Matrix const&) (Matrix.h:224) ==3352== by 0x8051C62: BOViL::algorithms::ExtendedKalmanFilter::setUpEKF(BOViL::math::Matrix, BOViL::math::Matrix, BOViL::math::Matrix) (ExtendedKalmanFilter.cpp:23) ==3352== by 0x804B74F: testSegmentation() (TestSegmentation.cpp:37) ==3352== by 0x805266D: main (main.cpp:16) ==3352== ==3352== Invalid write of size 8 ==3352== at 0x804CC12: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:283) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== Address 0x6a8d210 is 0 bytes after a block of size 48 alloc'd ==3352== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3352== by 0x804CBD8: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:279) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== ==3352== Invalid read of size 8 ==3352== at 0x804CC55: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:285) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== Address 0x6a8d210 is 0 bytes after a block of size 48 alloc'd ==3352== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3352== by 0x804CBD8: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:279) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== ==3352== Invalid write of size 8 ==3352== at 0x804CC95: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:285) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== Address 0x6a8d210 is 0 bytes after a block of size 48 alloc'd ==3352== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3352== by 0x804CBD8: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:279) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== --3352-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting --3352-- si_code=1; Faulting address: 0x6F666562; sp: 0x6800fa88 valgrind: the 'impossible' happened: Killed by fatal signal ==3352== at 0x380C0AD4: ??? (in /usr/lib/valgrind/memcheck-x86-linux) ==3352== by 0x380C12C5: ??? (in /usr/lib/valgrind/memcheck-x86-linux) ==3352== by 0x38040A63: ??? (in /usr/lib/valgrind/memcheck-x86-linux) ==3352== by 0x38040B36: ??? (in /usr/lib/valgrind/memcheck-x86-linux) ==3352== by 0x3803EA4B: ??? (in /usr/lib/valgrind/memcheck-x86-linux) ==3352== by 0x74206572: ??? sched status: running_tid=1 Thread 1: status = VgTs_Runnable ==3352== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3352== by 0x804BD52: BOViL::math::Matrix::Matrix(double const*, int, int) (Matrix.h:118) ==3352== by 0x804CCF3: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:290) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) 

E qui frammenti del codice:

-> Interfaccia Matrix

  template  class Matrix{ public: // Main interface Matrix(); // Default constructor Matrix(int _cols, int _rows); // Empty matrix constructor Matrix(const type_* _mat, int _rows, int _cols); // Full-defined matrix constructor Matrix(const Matrix& _mat); // Copy constructor Matrix(Matrix&& _mat); // Move constructor c++11 ~Matrix(); // De-constructor type_* getMatrixPtr() const; int getWidth() const; int getHeight() const; void showMatrix() const; public: // Overloaded Operators std::string operator<<(const Matrix& _mat) const; // Operator for cout 666 TODO: type_& operator[](int _index); Matrix operator=(const Matrix& _mat); // Assignement operator Matrix operator+(const Matrix& _mat) const; // Add operator Matrix operator-(const Matrix& _mat) const; // Sub operator Matrix operator*(const Matrix& _mat) const; // Mul operator Matrix operator*(const type_ _scalar) const; // Scalar operator Matrix operator^(const double _exp) const; // Pow operator 666 TODO: public: // Other operations 666 TODO: Change names Matrix operator&(const Matrix& _mat) const; // Projection operator._mat is projected to this Matrix transpose(); // Transpose operator type_ determinant(); // Determinant operator public: // Various algorithms double norm(); bool decompositionLU(Matrix& _L, Matrix& _U); bool decompositionCholesky(Matrix& _L, Matrix& _Lt); bool decompositionLDL(Matrix& _L, Matrix& _D, Matrix& _Lt); bool decompositionQR_GR(Matrix& _Q, Matrix& _R); // QR decomposition using Householder reflexions algorithm. Matrix inverse(); // Using QR algorithm private: // Private interface int mCols, mRows; type_* mPtr; }; 

-> E qui è dove matrice crash:

 void ExtendedKalmanFilter::forecastStep(const double _incT){ updateJf(_incT); mXfk = mJf * mXak; <<<----- HERE CRASH, inside operator* mP = mJf * mP * mJf.transpose() + mQ; } 

Per essere precisi, si blocca all’interno della matrice del costruttore (type_ * ptr, int _cols, int _rows); durante l’inizializzazione del puntatore

 template Matrix Matrix::operator* (const Matrix& _mat) const{ if(mCols !=_mat.mRows) assert(false); type_* ptr = new type_[mRows*_mat.mCols]; for(int i = 0; i < mRows ; i ++ ){ for(int j = 0 ; j < mCols ; j ++){ ptr[_mat.mCols * i + j] = 0; for(int k = 0 ; k < _mat.mRows ; k ++){ ptr[_mat.mCols * i + j] += mPtr[mCols * i + k] * _mat.mPtr[_mat.mCols * k + j]; } } } Matrix mat(ptr, mRows, _mat.mCols); <<< ----- HERE delete[] ptr; return mat; } template Matrix::Matrix(const type_* _matPtr, int _rows, int _cols): mPtr(new type_[_cols*_rows]), mCols(_cols), mRows(_rows) { <<<---- CRASH before getting into (So I suppose that crash in the new type_[_cols*_rows] for(int i = 0; i < _cols*_rows ; i ++){ mPtr[i] = _matPtr[i]; } } 

Infine, il distruttore della class è:

 template Matrix::~Matrix(){ if(mPtr) delete[] mPtr; } 

Qualcuno può aiutarmi? Non riesco a trovare il problema che ho provato il debug con Visual Studio in Windows e con valgrind in linux.

Grazie in anticipo

Il tuo primo errore dice:

 ==3352== Invalid read of size 8 ==3352== at 0x804CC8F: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:285) ==3352== by 0x8051F91: BOViL::algorithms::ExtendedKalmanFilter::forecastStep(double) (ExtendedKalmanFilter.cpp:48) ==3352== by 0x8051F25: BOViL::algorithms::ExtendedKalmanFilter::stepEKF(BOViL::math::Matrix const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) ==3352== Address 0x6a8b3c0 is 0 bytes after a block of size 48 alloc'd ==3352== at 0x402B454: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==3352== by 0x804C986: BOViL::math::Matrix::operator=(BOViL::math::Matrix const&) (Matrix.h:224) ==3352== by 0x8051C62: BOViL::algorithms::ExtendedKalmanFilter::setUpEKF(BOViL::math::Matrix, BOViL::math::Matrix, BOViL::math::Matrix) (ExtendedKalmanFilter.cpp:23) ==3352== by 0x804B74F: testSegmentation() (TestSegmentation.cpp:37) ==3352== by 0x805266D: main (main.cpp:16) 

che in breve significa:

 ==3352== Invalid read of size 8 ==3352== at 0x804CC8F: BOViL::math::Matrix::operator*(BOViL::math::Matrix const&) const (Matrix.h:285) ==3352== Address 0x6a8b3c0 is 0 bytes after a block of size 48 alloc'd 

Sapendo che la tua matrice è double , significa che la matrice all’interno della matrice è allocata per contenere 6 elementi ( 48/sizeof double ). Tuttavia, si accede a 0 byte dopo il blocco, il che significa che si sta accedendo esattamente all’elemento indice 6.

Quindi ci sono due cose che devi verificare:

  1. 6 è corretto? La matrice dovrebbe contenere 6 elementi?
  2. Alla riga 285 di Matrix.h , che è probabile all’interno dei cicli for , non qui:

     Matrix mat(ptr, mRows, _mat.mCols); <<< ----- HERE 

    è necessario esaminare quali indici si stanno dando alla matrice. Probabilmente, troverai la matrice indicizzata a 6 ed è qui che dovresti capire perché .

Il tuo programma sembra avere un gran casino e la memoria si sta corrompendo. Questo è un po ‘difficile da trovare guardando il tuo frammento di codice.

Tuttavia, come hai menzionato nella tua domanda, puoi albind il tuo programma usando Valgrind. Quindi potresti voler albind il tuo programma (a.out).

$ valgrind –tool = memcheck –db-attach = yes ./a.out

In questo modo, Valgrind dovrebbe albind il programma nel debugger quando viene rilevato il primo errore di memoria in modo da poter eseguire il debug dal vivo (GDB). Questo dovrebbe essere il modo migliore per capire e risolvere il tuo problema.

Una volta che sei in grado di capire il tuo primo errore, correggilo e rieseguilo e vedi quali sono gli altri errori che stai ottenendo. Questa procedura dovrebbe essere eseguita fino a quando non viene segnalato alcun errore da parte di Valgrind.