簡體   English   中英

C ++ - 將值插入std :: map時出現分段錯誤

[英]C++ - Segmentation fault when inserting values into std::map

我正在嘗試用C ++構建一個圖形實例解析器,它將圖形節點作為輸入並將它們插入到由LEMON庫定義的SmartGraph類中。

該庫不允許我插入具有特定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中的值時崩潰,這是我之前寫過的地圖結構。 我用gdb檢查了這個,並且node和new_node_id都是正常整數,而instance_graph_ids上的現有值對我來說也很合適。 嘗試在gdb中的instance_graph_ids中調用find()或insert()會返回“嘗試獲取不在內存中的值的地址”錯誤。 我在這里想念什么?


用完整的示例進行編輯。 可以從https://snap.stanford.edu/data/oregon1_010331.txt.gz下載示例實例

您應該first_node_iterator->firstfirst_node_iterator->second更改為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(value是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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM