c++ - C++调试断言失败;表达式:列表迭代器不兼容

标签 c++ visual-studio visual-studio-2017 c++17 stdstack

我对C++还是相当陌生,到目前为止,我试图从这些详尽的错误消息中弄清楚。我真的陷入了困境,这根本没有任何意义。我在下面共享的代码是我正在处理的个人有向图头文件的一部分。我不会共享所有内容,因为它很长,其他部分似乎与我的问题无关。但如果需要,请指定,我将分享。现在,下面的功能是评估从给定的根顶点是否可以到达顶点(即节点)。为此,它采用了迭代定义的深度优先搜索。
代码可以编译,但是我一直在运行时收到此错误消息,这毫无意义,因为它似乎是由于将int推送到std::stack引起的(当我注释掉执行此操作的行时,代码将运行) 。这样它-> first是一个int。它是我的邻接列表中的索引,其类型为std::unordered_map,并且还表示顶点ID。
到目前为止,我尝试了两种不同的方法。我将它-> first分配给一个单独的int id变量,并尝试以这种方式进行推送。然后,我尝试将std::stack更改为std::stack ,并尝试将顶点而不是id推送为ints(并相应地配置了其余代码)。什么都没做,我仍然遇到同样的错误。
我正在使用Visual Studio 2017和MSVC编译器。
顶点类别:

template <typename T>
class Vertex {

private:
    int id; //Id of the vertex
    double weight; //Weight of the vertex
    T data; //Custom data to be stored inside the vertex

public:
    Vertex() {} //Default constructor. 
    Vertex(int x, double y, T d) : id(x), weight(y), data(d) {} //Constructor with custom data type T
    Vertex(int x, double y) : id(x), weight(y) {} //Alternative constructor without type T, for graph use only
    int getId() { return id; }
    double getWeight() { return weight; }
    T getData() { return data; }
};
DirectedGraph类(摘要):
template <typename T>
class DirectedGraph {

private:
    std::unordered_map<int, Vertex<T>> vertices; //Stores vertices
    std::unordered_map<int, std::unordered_map<int, double>> adj_list; //Stores the graph in adjacency list format. Inner-most double type variable stores edge weight.
    size_t n_edges; //Stores total number of edges
    size_t n_vertices; //Stores total number of vertices
    int is_acyclic; //Variable to record if the graph is acyclic or not. Convention for this is following, 1: Graph is acyclic, 0: Graph is not acyclic, -1: Not tested yet

public:

    DirectedGraph();
    ~DirectedGraph();

    bool contains(const int&) const; //Returns true if the graph contains the given vertex_id, false otherwise.
    bool adjacent(const int&, const int&); //Returns true if the first vertex is adjacent to the second, false otherwise.

    void addVertex(Vertex<T>&); //Adds the passed in vertex to the graph (with no edges).
    void addEdge(const int&, const int&, const double&); //Adds a weighted edge from the first vertex to the second.

    void removeVertex(const int&); //Removes the given vertex. Should also clear any incident edges.
    void removeEdge(const int&, const int&); //Removes the edge between the two vertices, if it exists.

    size_t inDegree(const int&); //Returns number of edges coming in to a vertex.
    size_t outDegree(const int&); //Returns the number of edges leaving a vertex.
    size_t degree(const int&); //Returns the degree of the vertex (both in edges and out edges).

    size_t numVertices(); //Returns the total number of vertices in the graph.
    size_t numEdges() const; //Returns the total number of edges in the graph.

    std::unordered_map<int, Vertex<T>> getVertices(); //Returns a vector containing all the vertices.
    Vertex<T> getVertex(const int& u_id); //Retruns specified vertex. If vertex doesn't exist, the id and weight of the returned vertex are both -1. 
    double getEdgeWeight(const int& u_id, const int& v_id); //Returns the weight of the specified edge. If the edge doesn't exist, it returns -1.

    std::vector<Vertex<T>> getNeighbours(const int&); //Returns a vector containing all the vertices reachable from the given vertex. The vertex is not considered a neighbour of itself.
    std::vector<Vertex<T>> getSecondOrderNeighbours(const int&); // Returns a vector containing all the second_order_neighbours (i.e., neighbours of neighbours) of the given vertex.
                                                              // A vector cannot be considered a second_order_neighbour of itself.
    bool reachable(const int&, const int&); //Returns true if the second vertex is reachable from the first (can you follow a path of out-edges to get from the first to the second?). Returns false otherwise.
    bool containsCycles(); // Return true if the graph contains cycles (there is a path from any vertices directly/indirectly to itself), false otherwise.

    std::vector<Vertex<T>> depthFirstTraversal(const int&); //Returns the vertices of the graph in the order they are visited in by a depth-first traversal starting at the given vertex.
    std::vector<Vertex<T>> breadthFirstTraversal(const int&); //Returns the vertices of the graph in the order they are visited in by a breadth-first traversal starting at the given vertex.

    /*
     * Following function is an iterative implementation of Dijkstra's SP algorithm.
     * It returns a pair consisting of an array of shortest distances to all other
     * vertices from the given root vertex u_id (vertices are identified via
     * indexes in the array such that shortest distance to vertex i is placed to
     * the i th element in the array), and a "previous vertex" unordered_map. (If
     * you are unsure about what a "previous vertex" list is,
     * see https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
     */
    std::pair<int *, std::unordered_map<int, int>> dijkstra(int u_id);
    std::pair<int, std::vector<Vertex<T>>> shortestPath(int u_id, int v_id); //This function finds the shortest path to a single given target vertex (v_id) from a given vertex (u_id) as a pair that contains <distance, path>

    std::vector<std::vector<Vertex<T>>> stronglyConnectedComponents(); //Identifies and returns strongly connected components as a vector of vectors
    std::vector<Vertex<T>> topologicalSort(); //Returns a topologically sorted list of the graph. It requires the graph to be acyclic. If the graph isn't acyclic, it returns an empty vector.


};
reachable()函数(我遇到问题的那个):
template <typename T>
bool DirectedGraph<T>::reachable(const int& u_id, const int& v_id)
{
    //This function is a Depth First Search Algorithm that halts when latter vertex is found
    //Returns true if v_id is reachable from u_id

    std::stack<int> track; //Stack for DFS
    bool* visited = new bool[numVertices()]{};
    track.push(u_id); 
    while (!track.empty()) 
    {
        bool found = false; 
        auto it = adj_list[track.top()].begin();
        while (it != adj_list[track.top()].end() && !found) 
        {   
            if (!visited[it->first])
            {
                if (it->first == v_id) 
                {
                    delete[] visited;
                    return true; 
                } 
                visited[it->first] = true;
                track.push(it->first);//  <--When I comment out this line, the code runs.
                found = true; 
            }
            ++it;
        }
        if (!found) { track.pop(); } 
    }
    delete[] visited;
    return false;
}
完整的错误消息:
调试断言失败!
Filec:\ Program Files(x86)\ Microsoft Visual Studio \ 2017 \ community \ vc \ tools \ msvc \ 14.15.26726 \ include \ list
线:240
表达式:列表迭代器不兼容

最佳答案

该代码正在比较不兼容的迭代器。比较来自不同容器实例的两个迭代器是非法的。该标准说:The domain of == for forward iterators is that of iterators over the same underlying sequence
代码不满足此要求,其中it可以迭代一个std::unordered_map<int, double>,而adj_list[track.top()]可以是另一个std::unordered_map<int, double>对象。这种不兼容性是由于更改了track.top()的值引起的,原因如下:

            track.push(it->first);//  <--When I comment out this line, the code runs.
当不在debug模式下运行时,由于编译器不再生成此验证代码,因此代码可能突然开始运行,但也可能浪费内存并以奇怪的方式崩溃。
错误非常明显:代码比较了来自不同容器对象的迭代器。迭代器必须来自同一容器对象。

关于c++ - C++调试断言失败;表达式:列表迭代器不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62877236/

相关文章:

C++11 STL 容器和线程安全

c++ - 在 matlab 中调用时无法在 C++ 中使用 opencv 读取图像

visual-studio - Visual Studio-我希望“转到定义”打开对象浏览器,而不是“元数据”

visual-studio-2017 - 服务结构错误: Not authorized to connect

c++ - 如何在 Windows 上使用 visual studio 2017 连接到 C++ 中的 sqlite 数据库?

c++ - 游戏王卡的效果

c++ - 状态检查总是一件有效的事情吗?

c#如何在启动另一个线程之前检查一个线程是否完成

c# - 为什么我不能将数据插入到我的数据库中?

c++ - C++ 中对运算符优先级的混淆