cpp – valgrind – 大小为8的无效读取

我疯了理解valgrind错误。 我有一个名为matrix的模板类,它有一些重载的操作符等…做一些math运算。 Matrixes在名为ExtendedKalmanFilter的类中使用。

这里是valgrind痕迹:

==3352== Invalid read of size 8 ==3352== at 0x804CC8F: BOViL::math::Matrix<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator=(BOViL::math::Matrix<double> const&) (Matrix.h:224) ==3352== by 0x8051C62: BOViL::algorithms::ExtendedKalmanFilter::setUpEKF(BOViL::math::Matrix<double>, BOViL::math::Matrix<double>, BOViL::math::Matrix<double>) (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<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::Matrix(double const*, int, int) (Matrix.h:118) ==3352== by 0x804CCF3: BOViL::math::Matrix<double>::operator*(BOViL::math::Matrix<double> 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<double> const&, double) (ExtendedKalmanFilter.cpp:39) ==3352== by 0x804B98F: testSegmentation() (TestSegmentation.cpp:53) ==3352== by 0x805266D: main (main.cpp:16) 

在这里代码片段:

– >matrix界面

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

– >这里是matrix崩溃的地方:

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

确切地说,它在构造器matrix(type_ * ptr,int _cols,int _rows)内部崩溃; 同时初始化指针

 template<typename type_> Matrix<type_> Matrix<type_>::operator* (const Matrix<type_>& _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<type_> mat(ptr, mRows, _mat.mCols); <<< ----- HERE delete[] ptr; return mat; } template<typename type_> Matrix<type_>::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]; } } 

最后,这个类的析构函数是:

 template<typename type_> Matrix<type_>::~Matrix(){ if(mPtr) delete[] mPtr; } 

任何人都可以帮我吗? 我无法find麻烦,我尝试用Windows中的Visual Studio和Linux中的valgrinddebugging。

提前致谢

你的第一个错误说:

 ==3352== Invalid read of size 8 ==3352== at 0x804CC8F: BOViL::math::Matrix<double>::operator*(BOViL::math::Matrix<double> 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<double> 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<double>::operator=(BOViL::math::Matrix<double> const&) (Matrix.h:224) ==3352== by 0x8051C62: BOViL::algorithms::ExtendedKalmanFilter::setUpEKF(BOViL::math::Matrix<double>, BOViL::math::Matrix<double>, BOViL::math::Matrix<double>) (ExtendedKalmanFilter.cpp:23) ==3352== by 0x804B74F: testSegmentation() (TestSegmentation.cpp:37) ==3352== by 0x805266D: main (main.cpp:16) 

简而言之就是:

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

知道你的matrix是double ,这意味着matrix内的数组被分配成包含6个元素( 48/sizeof double )。 但是,您正在访问该块之后的0个字节,这意味着您正在访问完全元素索引6。

所以你需要validation两件事情:

  1. 6是正确的吗? 数组是否应该包含6个元素?
  2. Matrix.h 285行可能在for循环中, 不在这里:

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

    你需要检查你给这个数组的索引。 可能的话,你会发现数组被索引在6,这就是你应该找出原因的地方

你的程序似乎有很大的混乱,内存被损坏。 通过查看你的代码片段,这是有点难以find。

然而正如你在你的问题中提到的那样,你可以使用Valgrind附加你的程序 所以你可能要附加你的程序(a.out)。

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

这样,Valgrind会在检测到第一个内存错误时将程序附加到debugging器中,以便您可以进行实时debugging(GDB)。 这应该是理解和解决您的问题的最佳方式。

一旦你能够找出你的第一个错误,修复它并重新运行,看看你正在得到什么是其他错误。这个步骤应该完成,直到Valgrind没有报告错误。