cpp - valgrind - Invalid read of size 8

匿名 (未验证) 提交于 2019-12-03 01:18:02

问题:

I'm getting mad understanding that valgrind error. I've got a template class called Matrix that has some overloaded operators etc... to do some mathematical operations. Matrixes are used inside a class called ExtendedKalmanFilter.

Here is the valgrind trace:

==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) 

And here fragments of the code:

--> Matrix interface

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

-->And here is where matrix crash:

void ExtendedKalmanFilter::forecastStep(const double _incT){     updateJf(_incT);      mXfk = mJf * mXak;  

To be precise, it crash inside the constructor matrix(type_* ptr, int _cols, int _rows); while initializing the pointer

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  mat(ptr, mRows, _mat.mCols);   Matrix::Matrix(const type_* _matPtr, int _rows, int _cols):  mPtr(new type_[_cols*_rows]),                                                                         mCols(_cols),                                                                         mRows(_rows)             { 

Finally, the destructor of the class is:

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

Can anyone help me? I cant find the trouble I tryed debugging with Visual Studio in windows and with valgrind in linux.

Thanks in advance

回答1:

Your first error says:

==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) 

which in short means:

==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 

Knowing that your matrix is of double, that means the array inside the matrix is allocated to contain 6 elements (48/sizeof double). However, you are accessing 0 bytes after the block, which means you are accessing exactly element index 6.

So there are two things that you need to verify:

  1. Is 6 correct? Should the array contain 6 elements?
  2. At line 285 of Matrix.h, which is likely inside the for loops, not here:

    Matrix mat(ptr, mRows, _mat.mCols); 

    you need to examine what indices you are giving to the array. Likely, you will find the array being indexed at 6 and that's where you should figure out why.



回答2:

Your program seems to have big mess and memory is getting corrupted. This is is bit difficult to find by looking out your code snippet.

However as you have mentioned in your question that you are able to attach your program using Valgrind. So you may want to attach your program(a.out).

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

This way Valgrind would attach your program in the debugger when your first memory error is detected so that you can do live debugging(GDB). This should be the best possible way to understand and resolve your problem.

Once you are able to figure it out your first error, fix it and rerun it and see what are other errors you are getting.This steps should be done till no error is getting reported by Valgrind.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!