Segfault尝试在类

时间:2016-06-27 21:08:02

标签: c++ boost boost-spirit boost-spirit-qi

我一直在使用boost :: spirit编写一些解析器代码并开始获得段错误。

我已经尽可能地简化了我的代码,以便于发布,请参阅下文。

当解析器回调addModule时,会在int的回推期间发生segfault。

Valgrind声称向量v_modules未初始化。在代码的早期,我可以看到它被初始化,所以我假设发生了一些内存垃圾。我尝试用这个较小的测试用程序重写它很多次都无济于事。任何帮助表示赞赏!

verilog.cpp:

#include "verilog.h"
#include <string>
#include <boost/spirit/include/qi.hpp>

Verilog::Verilog() {
  m_parser.verilog = this;
}
Verilog::~Verilog(){}

void Verilog::parse(string contents) {
  string::const_iterator iter = contents.begin();
  string::const_iterator end = contents.end();
  bool r = phrase_parse(iter,end,m_parser,boost::spirit::ascii::space);
}

void Verilog::addModule() {
  int new_mod = 1;
  v_modules.push_back(new_mod);
}

int main()
{
  Verilog* verilog = new Verilog();
  string contents = "hello";
  verilog->parse(contents);
}

verilog.h

#ifndef VERILOG_H
#define VERILOG_H

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/bind.hpp>

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

class Verilog
{

 public:
  Verilog();
  ~Verilog();
  void parse(string contents);
  void addModule() ;

  template <typename Iterator>
    struct verilog_parser : qi::grammar<Iterator, ascii::space_type>  
    {
    verilog_parser() : verilog_parser::base_type(module)
        {
          module = qi::eps[boost::bind(&Verilog::addModule, verilog)];
        }

      qi::rule<Iterator, ascii::space_type> module;

      Verilog* verilog;

    };

 private:
  std::vector<int>    v_modules;
  verilog_parser<string::const_iterator> m_parser;

};

#endif

1 个答案:

答案 0 :(得分:3)

您正在使用SendAsync,这会产生一个临时函数对象,该对象引用构造语法期间boost::bind成员指向的任何内容。

那不行。

你需要一个凤凰懒惰的演员,如果你希望它从verilog构造函数中设置后获取更改的值,你最好通过_reference引用this->verilog

老实说,代码看起来有点笨拙。为什么不使用Spirit的属性兼容性规则为您自动构建向量(或列表,集合,映射等)?

这是一个修复:

Verilog
  

请注意,这仍然会将泄漏的Verilog实例留在#include <boost/spirit/include/phoenix.hpp> namespace phx = boost::phoenix; // ... later module = qi::eps[phx::bind(&Verilog::addModule, phx::ref(verilog))]; 中。为什么在现代C ++中使用main

整合它:

<强> Live On Coliru

new