C++程序Segmentation Fault问题:Valgrind检测到Invalid write of size 8
问题描述
开发求解二维热方程的C++程序时出现Segmentation Fault,怀疑是内存访问问题但无法定位具体原因,相关代码及错误信息如下:
代码片段
myclass.h
#include <vector> using vector_double = std::vector<double>; using matrix2d = std::vector<std::vector<double>>; class Myclass{ protected: matrix2d matrix_; vector_double vector_; size_t dim; size_t maxT; double initValue; public: Myclass(); void routine(); };
myclass.cpp
#include "myclass.h" Myclass::Myclass() { size_t dim = 1001; size_t maxT = 1001; double initValue = 13.0; matrix2d matrix_(maxT+1, vector_double(dim,initValue)); vector_double vector_(dim); } void Myclass::routine() { vector_[0] = initValue; for(size_t t=1; t<maxT; t++) { vector_[0] = matrix_[t][0] + matrix_[t][0]; for(size_t i=1; i < dim-1; i++) { vector_[i] = matrix_[t][i-1] + matrix_[t][i] + matrix_[t][i+1]; } } }
so.cpp
#include "myclass.h" int main() { Myclass myobject; myobject.routine(); return 0; }
编译与运行命令
g++ -g -O1 *.cpp -o out valgrind --leak-check=yes ./out
错误信息
==25934== Memcheck, a memory error detector ==25934== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==25934== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==25934== Command: ./out ==25934== ==25934== Invalid write of size 8 ==25934== at 0x109217: Myclass::routine() (myclass.cpp:15) ==25934== by 0x109577: main (so.cpp:7) ==25934== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==25934== ==25934== ==25934== Process terminating with default action of signal 11 (SIGSEGV) ==25934== Access not within mapped region at address 0x0 ==25934== at 0x109217: Myclass::routine() (myclass.cpp:15) ==25934== by 0x109577: main (so.cpp:7) ==25934== If you believe this happened as a result of a stack ==25934== overflow in your program's main thread (unlikely but ==25934== possible), you can try to increase the size of the ==25934== main thread stack using the --main-stacksize= flag. ==25934== The main thread stack size used in this run was 8388608. ==25934== ==25934== HEAP SUMMARY: ==25934== in use at exit: 0 bytes in 0 blocks ==25934== total heap usage: 1,006 allocs, 1,006 frees, 8,136,784 bytes allocated ==25934== ==25934== All heap blocks were freed -- no leaks are possible ==25934== ==25934== For lists of detected and suppressed errors, rerun with: -s ==25934== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Segmentation fault (core dumped)
解决方案
问题根源是构造函数内的局部变量遮蔽了类成员变量:你在构造函数中定义了同名的局部变量dim、maxT、initValue、matrix_、vector_,导致类的成员变量始终处于未初始化状态(dim、maxT为随机值,matrix_、vector_是空容器),在routine()中访问这些未初始化的成员变量就会触发内存错误。
修正后的构造函数(直接赋值成员变量)
Myclass::Myclass() { dim = 1001; maxT = 1001; initValue = 13.0; matrix_ = matrix2d(maxT+1, vector_double(dim,initValue)); vector_ = vector_double(dim); }
更推荐的写法(成员初始化列表,效率更高)
Myclass::Myclass() : dim(1001), maxT(1001), initValue(13.0), matrix_(maxT+1, vector_double(dim, initValue)), vector_(dim) {}
另外,routine()中的循环逻辑本身是合法的:
t<maxT循环中,matrix_[t]的索引范围是1到1000,对应matrix_的大小1002(索引0到1001),无越界i < dim-1循环中,i最大为999,i+1=1000对应vector_和matrix_[t]的合法索引
修正后重新编译运行,内存错误即可解决。
内容的提问来源于stack exchange,提问作者nico_so
相关产品推荐
相关产品推荐

