cpp - valgrind -无效的读取大小为8
cpp - valgrind - Invalid read of size 8
我对valgrind错误的理解很生气。我有一个模板类称为矩阵,有一些重载操作符等…做一些数学运算。矩阵在一个名为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)
下面是代码片段:
->矩阵接口
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;
};
->这里是矩阵崩溃的地方:
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)中崩溃;初始化指针
时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;
}
有人能帮我吗?我试着在windows中使用Visual Studio调试,在linux中使用valgrind调试,却找不到问题。
Thanks in advance
您的程序似乎有很大的混乱和内存正在损坏。这一点很难通过查看您的代码片段来找到。
然而,正如您在问题中提到的,您可以使用Valgrind附加您的程序。所以你可能想要附加你的程序(a.out)。
$ valgrind——tool=memcheck——db-attach=yes ./a.out
这样,当你的第一个内存错误被检测到时,Valgrind会在调试器中附加你的程序,这样你就可以进行实时调试(GDB)。这应该是理解和解决问题的最好方法。
一旦你能够找出你的第一个错误,修复它并重新运行它,看看你得到了什么其他错误。这个步骤应该执行到没有错误被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== 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。
你需要验证两件事:
- 6正确吗?数组应该包含6个元素吗?
在
Matrix.h
的第285行,可能在for
循环中,而不是:Matrix<type_> mat(ptr, mRows, _mat.mCols); <<< ----- HERE
你需要检查你给数组的索引。很可能,你会发现数组被索引为6,这就是你应该找出为什么的地方。
- 芬威克树(BIT).找到具有给定累积频率的最小索引,单位为 O(logN)
- 正在将csv文件读取为双精度矢量
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 最小的CMake构建为Android
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 将"uint8_t"(从套接字读取)隐式转换为"char"安全吗
- 逐字读取文本文件中的每一行并转换为 int(无限循环或崩溃?
- 将"-01"替换为"-02" 英特尔编译器选项会导致 FPE 在较小的 for 循环行程计数中抛出
- 如何读取文本文件中的数据并为每列 c++ 分配数组
- 如何以滑动窗口方式从 std::bitset 读取位并将它们转换为 int?
- Valgrind 大小为 8 且地址 0x5b7e520 的读取无效,在大小为 16 的块内为 0 字节 free'd
- Gtkmm 窗口为空白,不显示任何小部件或标题
- 在向量中查找大于 0(或通常为 k)的最小元素的最佳方法是什么?
- 读取二进制文件并解释为整数
- 如何将我的小程序转换为用于项目的函数?
- 将一个小的 C 定义重写为"normal" C++函数
- Qt:无法直接为带有子项的小部件添加滚动条
- C++转换为 C# 读取文本以生成语句
- 搜索一组点,其长度总和最小为矩形.算法是什么