C++ 从队列弹出时理解引用中的分段错误

C++ 从队列弹出时理解引用中的分段错误,c++,c++11,segmentation-fault,queue,C++,C++11,Segmentation Fault,Queue,我有以下功能: std::vector<Node> BFS(Graph g, Node source, Node target) { std::queue<std::vector<Node> > q; std::vector<Node> path = {source}; q.push(path); while (!q.empty()) { std::vector<Node> cur_pat

我有以下功能:

std::vector<Node> BFS(Graph g, Node source, Node target) {
    std::queue<std::vector<Node> > q;
    std::vector<Node> path = {source};
    q.push(path);
    while (!q.empty()) {
        std::vector<Node> cur_path = q.front();
        q.pop();
        Node cur_node = cur_path[cur_path.size() - 1];
        if (cur_node.data == target.data) {
            return cur_path;
        }
        // for (int i = 0; i < g.edge_map[cur_path].size(); i++) {
        //     std::vector<Node> new_path = cur_path;
        //     new_path.push_back(g.edge_map[cur_path][i]);
        //     q.push(new_path);
        // }
    }
}
其中:

graph. yup
Segmentation fault (core dumped)
FWIW,我的图有一个edge_映射成员,它是一个映射,节点结构作为键,节点结构的向量作为值来表示图邻接列表。构造函数输出“图形”。是的,如果你需要更多信息,请告诉我

编辑2:为了完整起见,我将把它的其余部分包括进来,很抱歉说得太多,但我试图理解为什么会发生这种情况

图h:

#include <iostream>
#include <map>
#include <vector>

struct Node {
    int data;
    std::string color;
};

inline bool operator<(const Node & left, const Node & right) {
    return left.data < right.data;
}

class Graph {
public:

    std::map< Node, std::vector<Node> > edge_map;

    Graph();

    void add_neighbor(Node cur_node, Node new_node, bool both_ways=false);

    void remove_neighbor(Node cur_node, Node del_node, bool both_ways=false);

    void print_neighbors(Node cur_node);

    virtual ~Graph();
};
#包括
#包括
#包括
结构节点{
int数据;
字符串颜色;
};
内联布尔算子边缘映射;
图();
void add_neighbor(Node cur_Node,Node new_Node,bool two_ways=false);
void remove_neighbor(Node cur_Node、Node del_Node、bool two_ways=false);
无效打印邻居(节点当前节点);
虚~图();
};
graph.cpp:

#include <iostream>
#include <vector>
#include <algorithm>
#include "graph.h"
#include <map>

Graph::Graph() {
    std::cout << "graph. yup" << std::endl;
}


void Graph::add_neighbor(Node cur_node, Node new_node, bool both_ways) {
    edge_map[cur_node].push_back(new_node);
    if (both_ways) {
        edge_map[new_node].push_back(cur_node);
    }
}

void Graph::remove_neighbor(Node cur_node, Node del_node, bool both_ways) {
    // TODO: convert vector values in map of <Node, vector<Node> > into maps, so this function can be easy and have sensible complexity
    std::cout << "Not implemented yet." << std::endl;
    // if (both_ways) {
    //     edge_map[del_node].remove(cur_node);
    // }
    //this->edge_map[cur_node].erase(std::remove(this->edge_map[cur_node].begin(), this->edge_map[cur_node].end(), del_node), this->edge_map[cur_node].end());
}

void Graph::print_neighbors(Node cur_node) {
    for (int i = 0; i < edge_map[cur_node].size(); i++) {
        std::cout << edge_map[cur_node][i].data << " " << edge_map[cur_node][i].color << std::endl;
    }
}

Graph::~Graph() {
    std::cout << "ded graph :(" << std::endl;
}
#包括
#包括
#包括
#包括“graph.h”
#包括
Graph::Graph(){
std::cout edge_map[cur_node].end();
}
无效图::打印邻域(节点cur\u节点){
对于(int i=0;i
据我所知,可能会发生什么:

  • q、 pop调用std::vector的析构函数

  • ~std::vector会破坏每个节点

  • 也许节点析构函数做了一些非法的事情


一个巨大而明显的错误:

BFS
函数不会返回所有控制路径的值,即使它应该返回
std::vector
。因此程序具有未定义的行为。
BFS
返回的唯一路径是
while
循环中的条件语句:

 if (cur_node.data == target.data) {
            return cur_path;
但是,如果在运行外部
while
循环期间
cur_node.data
始终不等于
target.data
,则不会返回,从而触发未定义的行为(在您的情况下,是分段错误)

运行程序表明您正在导致未定义的行为。请注意,使用的编译器是Visual Studio 2015

但要显示未定义行为的后果,请注意,
gcc
将在不打印消息的情况下崩溃。要让它打印消息,必须使用
std::endl
刷新缓冲区以查看“麻烦!!”字符串

考虑到所有这些,由于必须返回某些内容,因此必须决定在找不到节点的情况下返回什么
,但是
BFS
的调用方如何确定该节点是否存在?我认为您需要理顺
BFS
的基本规则,以确定该函数的输出应该表示什么

此外:

可能只是:

Node cur_node = cur_path.back();

你的代码中没有一个引用。你能发布一个最小的可复制的示例吗?这是我的想法,但没有问题,所以这不涉及STL queue pop()的这个特定问题的引用造成segfaults,至少不是我能找到的。我会在中编辑一些信息。请发布一条消息,否则你不会得到太多帮助。@ilovicliques:这不是最简单或完整的。321最好的建议就是不要发布。发布弱答案会降低你获得评论权的能力。现在新信息已经到达,
struct Node{int data;std::string color;};
发现答案不正确。gdb bt给出:#0 0x00007FF7B240C0在std::basic_string::~basic_string()()中,来自/usr/lib/x86_64-linux-gnu/libstdc++。因此。6#1 0x0000000000402566在Node::~Node()中#3 0x0000000000402e10无效标准::#销毁(节点*,节点*)()#4 0x0000000000402bc2无效标准:#销毁(节点*,节点*)()#5 0x0000000000424AA无效标准:#销毁(节点*,节点*,标准::分配器&()((下一条注释中续#6 0x0000000000402C225标准::向量::~vector()#7 0x00000040000E2@ILOVELIQUE是正确的,但这不是析构函数的问题。这是因为被销毁的节点不存在。
Node cur_node = cur_path[cur_path.size() - 1];
Node cur_node = cur_path.back();