首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cpp - valgrind -读取大小8无效

cpp - valgrind -读取大小8无效
EN

Stack Overflow用户
提问于 2014-03-26 18:36:59
回答 2查看 17.4K关注 0票数 4

我对valgrind的错误越来越不理解了。我有一个名为Matrix的模板类,它有一些重载的运算符等。来做一些数学运算。矩阵在一个名为ExtendedKalmanFilter的类中使用。

下面是valgrind跟踪:

代码语言:javascript
复制
==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)

下面是代码片段:

-->矩阵界面

代码语言:javascript
复制
    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;

    };

-->这里是矩阵崩溃的地方:

代码语言:javascript
复制
void ExtendedKalmanFilter::forecastStep(const double _incT){
    updateJf(_incT);

    mXfk = mJf * mXak;  <<<----- HERE CRASH, inside operator*

    mP = mJf * mP * mJf.transpose() + mQ;
}

准确地说,在初始化指针时,它会在构造函数矩阵(type_* ptr,int _cols,int _rows)内崩溃

代码语言:javascript
复制
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];
        }
    }

最后,类的析构函数是:

代码语言:javascript
复制
template<typename type_> 
Matrix<type_>::~Matrix(){
    if(mPtr)
        delete[] mPtr;
}

有谁可以帮我?我找不到调试windows中的Visual Studio和linux中的valgrind的麻烦。

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-26 18:52:37

你的第一个错误是:

代码语言:javascript
复制
==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)

简而言之,这意味着:

代码语言:javascript
复制
==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

知道您的矩阵是double的,这意味着矩阵中的数组被分配为包含6个元素(48/sizeof double)。但是,您访问的是块之后的0个字节,这意味着您访问的是元素索引6。

因此,您需要验证两件事:

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

Matrix> mat(ptr,mRows,_mat.mCols);<<< -此处

您需要检查您为数组指定了哪些索引。很可能,您会发现索引位置为6的数组,这就是您应该找出原因的地方。

票数 4
EN

Stack Overflow用户

发布于 2014-03-26 18:51:52

你的程序看起来乱七八糟,内存也被破坏了。通过查看您的代码片段很难找到这一点。

但是,正如您在问题中提到的,您可以使用Valgrind.附加您的程序,因此您可能希望附加您的程序(a.out)。

$ valgrind --工具=内存检查--db-attach=是。/a.out

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

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

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22658313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档