我正在尝试使用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
下载示例实例答案 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;
}