cpp – valgrind – lectura inválida de tamaño 8

Me estoy enojando al entender que valgrind error. Tengo una clase de plantilla llamada Matrix que tiene algunos operadores sobrecargados, etc … para hacer algunas operaciones matemáticas. Las matrices se usan dentro de una clase llamada ExtendedKalmanFilter.

Aquí está el rastro 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) 

Y aquí fragmentos del código:

-> Interfaz de matriz

  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; }; 

-> Y aquí es donde falla la matriz:

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

Para ser precisos, se bloquea dentro de la matriz del constructor (type_ * ptr, int _cols, int _rows); al inicializar el puntero

 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]; } } 

Finalmente, el destructor de la clase es:

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

¿Alguien puede ayudarme? No puedo encontrar el problema que probé al depurar con Visual Studio en Windows y con valgrind en Linux.

Gracias por adelantado

Tu primer error 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) 

que en resumen 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 

Sabiendo que su matriz es double , eso significa que la matriz dentro de la matriz está asignada para contener 6 elementos ( 48/sizeof double ). Sin embargo, está accediendo a 0 bytes después del bloque, lo que significa que está accediendo exactamente al índice 6 del elemento.

Entonces, hay dos cosas que necesita verificar:

  1. ¿Son 6 correctos? ¿Debería la matriz contener 6 elementos?
  2. En la línea 285 de Matrix.h , que probablemente esté dentro de los bucles for , aquí no :

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

    necesita examinar qué índices le está dando a la matriz. Probablemente, encontrará la matriz indexada en 6 y ahí es donde debería averiguar por qué .

Su progtwig parece tener un gran lío y la memoria se corrompe. Esto es un poco difícil de encontrar mirando su fragmento de código.

Sin embargo, como mencionó en su pregunta, puede adjuntar su progtwig usando Valgrind. Por lo tanto, es posible que desee adjuntar su progtwig (a.out).

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

De esta forma, Valgrind adjuntará su progtwig en el depurador cuando se detecte su primer error de memoria para que pueda realizar la depuración en vivo (GDB). Esta debería ser la mejor manera posible de comprender y resolver su problema.

Una vez que sea capaz de resolver su primer error, arréglelo, vuelva a ejecutarlo y vea qué otros errores está recibiendo. Estos pasos deben realizarse hasta que Valgrind no haya informado ningún error.