C ++-将值插入std :: map

时间:2019-03-14 23:42:21

标签: c++ lemon-graph-library

我正在尝试使用C ++构建图实例解析器,该解析器将图节点作为输入并将其插入LEMON库定义的SmartGraph类中。

该库不允许我插入具有特定ID的节点(据我在文档中所看到的),因此我创建了一个并行结构来存储输入文件和ID的节点ID之间的关系。我的代码中实际图形的节点ID(可能有一个聪明的解决方法,但是我并没有考虑太多,只要实例不那么大,就可以了)我内存不足,几乎是不可能的)。为此,我使用的是std :: map,它将输入文件ID作为键,并将图形节点ID作为值。

如果我只是执行程序,此std :: map就会在循环的迭代号239中崩溃,该循环将从输入文件中读取行,如果我用Valgrind对其进行检查,它将变为2252,这使我认为我必须进行很大的监督并在某处泄漏内存,但我无法弄清楚。代码如下

#include <lemon/smart_graph.h>
#include <lemon/concepts/graph.h>
#include <iostream>
#include <fstream>
#include <map>
#include <string>

using std::cout;
using std::cin;
using std::getline;
using std::vector;
using std::string;
using std::stringstream;
using std::exception;
using std::ifstream;
using std::ios;
using std::map;

using lemon::SmartGraph;

map<int, int> instance_graph_ids;
map<int, int>::iterator it;
SmartGraph graph;
ifstream input_instance("instance.txt", ios::in);
string current_line;
while (getline (input_instance, current_line))
    {
        stringstream stream(current_line);
        string buffer;
        vector <int> separated_nodes;
        while(getline(stream, buffer, '\t')){
            separated_nodes.push_back(stoi(buffer));
        };
        for (int node : separated_nodes){
            it = instance_graph_ids.find(node);
            if (it == instance_graph_ids.end())
                {
                    int new_node_id;
                    SmartGraph::Node new_node = graph.addNode();
                    new_node_id = graph.id(new_node);
                    instance_graph_ids.insert({ node, new_node_id });
                };
        };
        auto first_node_iterator = instance_graph_ids.find(separated_nodes[0]);
        auto second_node_iterator = instance_graph_ids.find(separated_nodes[1]);
        graph.addEdge( graph.nodeFromId(first_node_iterator -> first),graph.nodeFromId(second_node_iterator -> second));
    }

我知道这很丑陋,但在尝试进行细化之前,我正在尝试使其工作,所以请在这里忍受。 node是输入文件中节点的ID,以整数表示。尝试.insert()instance_graph_ids中的值时会崩溃,instance_graph_ids是我之前写过的映射结构。我已经用gdb进行了检查,node和new_node_id都是普通整数,instance_graph_ids上的现有值对我来说也可以。尝试在gdb的instance_graph_ids中调用find()或insert()会返回“尝试获取不在内存中的值的地址”错误。我在这里想念什么?


以完整示例进行编辑。可以从https://snap.stanford.edu/data/oregon1_010331.txt.gz

下载示例实例

1 个答案:

答案 0 :(得分:0)

您应将first_node_iterator->first更改为first_node_iterator->second

graph.addEdge(graph.nodeFromId(first_node_iterator->second),
              graph.nodeFromId(second_node_iterator->second));

例如,在处理“ 10000 4725”的第一行时
使用std :: vector将节点存储在SmartGraph中,
graph.addEdge时,std :: vector上只有两个元素,
您使用first_node_iterator-> first(值是10000)作为下标,这超出范围。

修改后的代码:

#include <lemon/smart_graph.h>
#include <lemon/concepts/graph.h>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <assert.h>

using std::cout;
using std::cin;
using std::getline;
using std::vector;
using std::string;
using std::stringstream;
using std::exception;
using std::ifstream;
using std::ios;
using std::map;

using lemon::SmartGraph;

int main()
{
    map<int, int> instance_graph_ids;
    map<int, int>::iterator it;
    SmartGraph graph;
    ifstream input_instance("instance.txt", ios::in);
    string current_line;

    while (getline (input_instance, current_line)) {
        stringstream stream(current_line);
        string buffer;
        vector <int> separated_nodes;

        while (getline(stream, buffer, '\t')) {
            separated_nodes.push_back(stoi(buffer));
        };

        for (int node : separated_nodes) {
            it = instance_graph_ids.find(node);

            if (it == instance_graph_ids.end()) {
                int new_node_id;
                SmartGraph::Node new_node = graph.addNode();
                new_node_id = graph.id(new_node);
                instance_graph_ids.insert({ node, new_node_id });
            };
        };

        auto first_node_iterator = instance_graph_ids.find(separated_nodes[0]);
        auto second_node_iterator = instance_graph_ids.find(separated_nodes[1]);

        assert(first_node_iterator->second < graph.nodeNum());
        graph.addEdge(graph.nodeFromId(first_node_iterator->second),
                      graph.nodeFromId(second_node_iterator->second));
    }

    return 0;
}