c – Boost :: Regex Segfault(我认为)

我遇到了一些我正在运行的C代码的问题.基本上,它适用于大多数输入,但在某些输入后,我的主函数返回后会出现段错误.这一直……令人费解.我在segfault停止运行以获得堆栈跟踪,并返回此信息:

#0 malloc_consolidate() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4151
#1 _int_free() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4057
#2 boost::re_detail::mem_block_cache::~mem_block_cache()() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0
#3 __cxa_finalize() at /build/eglibc-oGUzwX/eglibc-2.19/stdlib/cxa_finalize.c:56
#4 ??() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0
#5 ??() at 
#6 _dl_fini() at /build/eglibc-oGUzwX/eglibc-2.19/elf/dl-fini.c:252

这让我觉得我必须对强制正则表达式做错事,但我不能为我的生活搞清楚.我正在使用正则表达式的方式是用户可以输入一串字符串.这些字符串可以只是普通文本,也可以是正则表达式.因此,我基本上将所有输入作为正则表达式进行交互.但是,如果用户给出了一个字符串,该字符串用作纯文本但具有可以作为正则表达式进行不同解释的字符呢?我所做的是浏览所有纯文本输入字符串并转义所有这些字符.

这是我正在使用的代码.这是我的主要内容:

int
main(int argc, char * argv[])
{

    // Process input arguments
    // The desired input is numVertices (int), graph density (double between 0 and 1), halfLoss (double), total loss (double),
    // position expanse (double, m), velocity expanse (double, m/s)
    int num_vertices;
    double graph_density ;
    double half_loss;
    double total_loss;
    double position_expanse;
    double velocity_expanse;

    if (argc == 1)
    {
        num_vertices = 48;
        graph_density = 1;
        half_loss = 200000;
        total_loss = 400000;
        position_expanse = 400000;
        velocity_expanse = 10000;
    }
    else
    {
        if (argc != 7)
        {
            std::cerr << "Need 6 input arguments" << std::endl;
            return 1;
        }

        std::istringstream ss(argv[1]);
        num_vertices;
        if (!(ss >> num_vertices))
            std::cerr << "First input must be an integer" << std::endl;

        graph_density = read_double_input(argv[2]);
        half_loss = read_double_input(argv[3]);
        total_loss = read_double_input(argv[4]);
        position_expanse = read_double_input(argv[5]);
        velocity_expanse = read_double_input(argv[6]);
    }

    // Determine how many edges to create
    int num_edges = (int) ( (graph_density * num_vertices * (num_vertices - 1)) + 0.5 );

    // Create the edges
    int edges_created = 0;
    std::set<std::pair<int, int> > edge_set;
    while (edge_set.size() < num_edges)
    {

        // Pick a random start vertex and end vertex
        int start_vertex = rand() % num_vertices;
        int end_vertex = rand() % num_vertices;

        // Make sure the start and end vertices are not equal
        while (start_vertex == end_vertex)
        {
            end_vertex = rand() % num_vertices;
        }

        // Insert the new edge into our set of edges
        edge_set.insert(std::pair<int, int>(start_vertex, end_vertex));

    }

    // Create connection handler
    ConnectionHandler conn_handler;

    // Create lists for from and to vertices
    std::vector<std::string> from_list;
    std::vector<std::string> to_list;

    // Add connections to from and to lists
    for (std::set<std::pair<int, int> >::const_iterator edge_it = edge_set.begin(), end_it = edge_set.end(); edge_it != end_it; ++edge_it)
    {
        int start_vertex = edge_it->first;
        int end_vertex = edge_it->second;
        from_list.push_back("Radio" + int_to_string(start_vertex));
        to_list.push_back("Radio" + int_to_string(end_vertex));
    }

    // Read the list into the connection handler
    conn_handler.read_connection_list(true, from_list, to_list);    
    return 0;

}

此代码具有我创建的ConnectionHandler对象.这是标题:

#ifndef CLCSIM_CONNECTIONHANDLER_HPP_
#define CLCSIM_CONNECTIONHANDLER_HPP_

#include <models/network/NetworkTypes.hpp>
#include <generated/xsd/NetworkModelInterfaceConfig.hpp>

namespace clcsim
{

typedef std::map<std::string, std::set<std::string> > ConnectionFilter;

class ConnectionHandler
{

public:

    ConnectionHandler();
    ~ConnectionHandler();

    void read_connection_list(const bool is_white_list, const std::vector<std::string> &from_radios, const std::vector<std::string> &to_radios);


private:

    ConnectionFilter filter_;
    std::set<std::string> from_list_;
    std::set<std::string> to_list_;
    bool is_white_list_;

};

} // namespace clcsim

#endif // CLCSIM_CONNECTIONHANDLER_HPP_

以下是来源:

#include <models/network/ConnectionHandler.hpp>
#include <oasis/framework/exceptions/ConfigurationException.h>
#include <boost/regex.hpp>

namespace clcsim 
{

ConnectionHandler::
ConnectionHandler()
{
}

ConnectionHandler::
~ConnectionHandler()
{
    std::cout << "Destructing conn handler" << std::endl;
}

void 
ConnectionHandler::
read_connection_list(
    const bool is_white_list, 
    const std::vector<std::string> &from_radios, 
    const std::vector<std::string> &to_radios)
{

    std::cout << "Reading the connection list" << std::endl;

    // Make sure the size of both the input vectors are the same
    std::size_t from_radio_size = from_radios.size();
    std::size_t to_radio_size = to_radios.size();
    if (from_radio_size != to_radio_size)
    {
        throw ofs::ConfigurationException("Error while initializing the "
                                          "Network model: "
                                          "Connections in from/to lists don't align"
                                         );
    }

    // Create a regular expression/replacement to find all characters in a non-regular expression
    // that would be interpreted as special characters in a regular expression. Replace them with
    // escape characters
    const boost::regex esc("[.$|()\\[\\]{}*+?\\\\]");
    const std::string rep("\\\\&");

    // Iterate through the specified connections
    for (int i = 0; i < from_radio_size; ++i)
    {

        std::string from_string = boost::regex_replace(from_radios[i], esc, rep, boost::match_default | boost::format_sed);
        std::string to_string = boost::regex_replace(to_radios[i], esc, rep, boost::match_default | boost::format_sed);
        //std::cout << "From " << from_string << " to " << to_string << std::endl;
        filter_[from_string].insert(to_string);
        //filter_[from_radios.at(i)].insert(to_radios.at(i));
    }

    std::cout << "Got here" << std::endl;

}


} // namespace clcsim

很抱歉这么多代码.

我通过boost :: regex看到了一些与segfaults相关的类似线程.在这些示例中,用户拥有非常简单的代码,只是创建了一个正则表达式并匹配它并遇到了错误.原来这个问题与Boost版本有关.我试着看看我是否可以复制那些错误,但这些简单的例子对我来说效果很好.所以……我很难过.我真的很感激任何帮助!

最佳答案 为了从“未答复”列表中删除它,我将发布评论中提供的答案而不是此处. OP确定Boost链接到eglibc的建议确实与其他与glibc相关的代码冲突.因此,OP发现升级他的操作系统以便不再使用eglibc链接库来解决问题.

点赞