关于视觉SLAM十四讲第九章0.2中在执行run_vo时出现Segmentation fault (core dumped)时解决方法

d在视觉SLAM十四讲第九章0.2中,执行run_vo时出现了Segmentation fault (core dumped)错误,通过gdb调试发现和cv::FileStorage有关(可能您的错误源和我的不同,在网上发现有不一样的地方)。通过对run_vo中的语句定位(屏蔽掉所有的语句,再逐句试试)发现是和config.h文件中的config类定义有关。在Config类定义如下:

class Config
{
private:
    static std::shared_ptr config_; 
    cv::FileStorage file_;
    
    Config () {} // private constructor makes a singleton
public:
    ~Config();  // close the file when deconstructing 
    
    // set a new config file 
    static void setParameterFile( const std::string& filename ); 
    
    // access the parameter values
    template< typename T >
    static T get( const std::string& key )
    {
        return T( Config::config_->file_[key] );
    }
};

此类中的config_是静态指针,所以所有的Config类的对象都可以共享此指针。但通过使用此类中的setParameterFile函数设定过config_所指向的对象后,再调用此类中的get()函数就会发生Segmentation fault (core dumped)错误。

setParameterFile()函数的定义如下:

void Config::setParameterFile( const std::string& filename )
{
    if ( config_ == nullptr )
        config_ = shared_ptr(new Config);
    config_->file_ = cv::FileStorage( filename.c_str(), cv::FileStorage::READ );
    if ( config_->file_.isOpened() == false )
    {
        std::cerr<<"parameter file "<         config_->file_.release();
        return;
    }
}

经过各种改动后都没有很好的效果,后来在上述函数中添加了一个静态cv::FileStorage对象后解决了这个错误。方法如下:

void Config::setParameterFile( const std::string& filename )
{
    if ( config_ == nullptr )
        config_ = shared_ptr(new Config);
static cv::FileStorage file1( filename.c_str(), cv::FileStorage::READ );
    config_->file_ = file1;

    if ( config_->file_.isOpened() == false )
    {
        std::cerr<<"parameter file "<         config_->file_.release();
        return;
    }
}

在主CMakeLists.txt中将

set( CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3" )中的-march=native -O3删除(这一步我也搞不明白),改为:

set( CMAKE_CXX_FLAGS "-std=c++11" )

 

具体原因我也不想清楚,我猜测是,config->file_包含的只是file1地址的拷贝,file1的内容还是在file1定义的时候分配的地方存着,如果file1是非静态的,此时file1相当于函数内部的临时变量,在setParameterFile函数执行完后,函数内部定义的临时变量就会被销毁,这样config->file_就指向了一个已经销毁的内容,所以就会出现Segmentation fault (core dumped)错误。

在原文件中congfig->file_是直接被赋值的,我觉得此时是相对于将一个无名的cv::FileStorage临时变量赋值给了file_,所以和有名file1是一样的。也许可以把这个无名的变量称为盗墓笔记里的他,看不见却存在着。

以上原因纯属个人猜测,有错误的地方还希望提出多多交流,本人c++知识掌握的一般,不足之处还请多多指教。

 

 

如果转载请注明出处。

 

你可能感兴趣的:(关于视觉SLAM十四讲第九章0.2中在执行run_vo时出现Segmentation fault (core dumped)时解决方法)