gpt4 book ai didi

c++ - valgrind:无效写入

转载 作者:太空宇宙 更新时间:2023-11-04 16:30:50 27 4
gpt4 key购买 nike

在下面的代码中:

void ResourceFitter::copyToLarvalResources( const gsl_vector* input ){
assert( input->size == invLarvalResources.size() );
if( invLarvalResources.size() != 365 ){
cout<<"error: iLR.size(): "<<invLarvalResources.size()<<endl;
exit(21);
}
// inverting larval resources may help fitting algorithm, so we do that here:
for( size_t i=0; i<invLarvalResources.size(); ++i ){
if( i >= 365 ){
cout<<"error: i="<<i<<endl;
exit(22);
}
double val = gsl_vector_get( input, i );
invLarvalResources[i] = 1.0 / val;
}
}

这是 ResourceFitter.cpp 中的几行。第 380 行是最后一行代码(在 invLarvalResources 中分配)。 invLarvalResources 是一个 vector<double> .

valgrind 提示:

==30152== Invalid write of size 8
==30152== at 0x8ED3E5: OM::Transmission::Vector::ResourceFitter::copyToLarvalResources(gsl_vector const*) (ResourceFitter.cpp:380)
==30152== by 0x8ECE99: OM::Transmission::Vector::ResourceFitter::sampler(gsl_vector const*) (ResourceFitter.cpp:334)
==30152== by 0x8EB64D: OM::Transmission::Vector::ResourceFitter_minimise_sampler(gsl_vector const*, void*) (ResourceFitter.cpp:88)
==30152== by 0x4F3249A: ??? (in /usr/lib/libgsl.so.0.16.0)
==30152== by 0x8ED5C4: OM::util::MultidimMinimiser::MultidimMinimiser(gsl_multimin_fminimizer_type const*, unsigned long, double (*)(gsl_vector const*, void*), void*, gsl_vector*, gsl_vector*) (MultidimSolver.h:71)
==30152== by 0x8EC45E: OM::Transmission::Vector::ResourceFitter::fit(unsigned long, OM::Transmission::Vector::ResourceFitter::FitMethod, unsigned long) (ResourceFitter.cpp:217)
==30152== by 0x8EC308: OM::Transmission::Vector::ResourceFitter::fit() (ResourceFitter.cpp:183)
==30152== by 0x8E474F: OM::Transmission::Vector::SpeciesModel::init2(unsigned long, std::list<OM::Host::Human, std::allocator<OM::Host::Human> > const&, int, double) (SpeciesModel.cpp:393)
==30152== by 0x8DA29E: OM::Transmission::VectorModel::init2(std::list<OM::Host::Human, std::allocator<OM::Host::Human> > const&, int) (VectorModel.cpp:163)
==30152== by 0x81C08F: OM::Population::createInitialHumans() (Population.cpp:165)
==30152== by 0x8172E8: OM::Simulation::start() (Simulation.cpp:120)
==30152== by 0x816615: main (openMalaria.cpp:53)
==30152== Address 0x8ca3d10 is 0 bytes inside a block of size 2,920 free'd
==30152== at 0x4C2658C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30152== by 0x822515: __gnu_cxx::new_allocator<double>::deallocate(double*, unsigned long) (new_allocator.h:98)
==30152== by 0x81FDBB: std::_Vector_base<double, std::allocator<double> >::_M_deallocate(double*, unsigned long) (stl_vector.h:156)
==30152== by 0x81FC98: std::_Vector_base<double, std::allocator<double> >::~_Vector_base() (stl_vector.h:142)
==30152== by 0x81E82B: std::vector<double, std::allocator<double> >::~vector() (stl_vector.h:351)
==30152== by 0x8DB5D2: OM::Transmission::Vector::MosqLifeCycleParams::~MosqLifeCycleParams() (in /home/dhardy/code/openmalaria/build-debug/openMalaria)
==30152== by 0x8DBA24: OM::Transmission::Vector::MosquitoTransmission::~MosquitoTransmission() (in /home/dhardy/code/openmalaria/build-debug/openMalaria)
==30152== by 0x8E4719: OM::Transmission::Vector::SpeciesModel::init2(unsigned long, std::list<OM::Host::Human, std::allocator<OM::Host::Human> > const&, int, double) (SpeciesModel.cpp:391)
==30152== by 0x8DA29E: OM::Transmission::VectorModel::init2(std::list<OM::Host::Human, std::allocator<OM::Host::Human> > const&, int) (VectorModel.cpp:163)
==30152== by 0x81C08F: OM::Population::createInitialHumans() (Population.cpp:165)
==30152== by 0x8172E8: OM::Simulation::start() (Simulation.cpp:120)
==30152== by 0x816615: main (openMalaria.cpp:53)

调试行 (cout<<...) 永远不会被打印出来。那么从 valgrind 的说法来看,invLarvalResources 似乎被释放了?从查看似乎并非如此的代码来看,在那种情况下,valgrind 不应该提示之前对 invLarvalResources 的读取吗?

那么 valgrind 在这方面是完全错误还是其他原因?在没有 valgrind 的情况下运行我没有遇到这个问题,但我确实得到了一个奇怪的数字结果,这在孤立的单元测试中找不到。在解决另一个错误之前,我还遇到了 SIGSEGV(我适度确定不应该导致 SIGSEGV)。

构建标志是 -g -rdynamic,编译器是 gcc 4.6.1 via ccache。如果您想要完整的资源,我会非常乐意为您指出:svn co http://openmalaria.googlecode.com/svn/branches/vec-lifecycle

如有任何帮助,我们将不胜感激!

最佳答案

你那里有很多代码......

快速浏览一下就会发现 invLarvalResources是对 vector引用属于 MosqLifeCycleParams .

发生的事情是你传递了一个 MosquitoTransmission 按值到您的ResourceFitter构造函数。当该对象被销毁时 - 即构造函数返回时 - 它会销毁其 MosqLifeCycleParams ,它恰好拥有您刚刚存储的引用的 vector 。
随之而来的是欢闹。

您需要更加小心引用和所有权(包括您返回私有(private)变量的非常量引用的习惯。这使它们有效地公开。)

寓意:当您认为您在工具中发现了错误时,它很可能是您的代码中的错误。

关于c++ - valgrind:无效写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7206145/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com