C++ 调试断言失败;表达式:列表迭代器不兼容
C++ Debug Assertion Failed; Expression: list iterators incompatible
我是 C++ 的新手,到目前为止,我正在尝试理解这些令人筋疲力尽的错误消息。我真的陷入了这个,它真的毫无意义。我在下面分享的代码是我正在处理的个人有向图头文件的一部分。我不会分享所有内容,因为它有点长,而且其他部分似乎与我的问题无关。但如果需要请说明,我会分享。现在下面的函数是评估一个顶点(即节点)是否可以从给定的根顶点到达。它采用迭代定义的深度优先搜索来执行此操作。
代码编译但我在运行时不断收到此错误消息,这根本没有意义,因为它似乎是由于将 int 推入 std::stack 引起的(当我注释掉我所做的行时这,代码运行)。这样 it->first 就是一个 int。它是我的邻接列表中的一个索引,类型为 std::unordered_map,也代表一个顶点 ID。
到目前为止,我尝试了两种不同的方法。我将 it->first 分配给一个单独的 int id 变量并尝试以这种方式推送它。我尝试将 std::stack 更改为 std::stack 并尝试将顶点而不是 id 作为整数推送(并相应地配置其余代码)。没有任何效果,我仍然得到同样的错误。
我正在使用 Visual Studio 2017 和 MSVC 编译器。
顶点Class:
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; }
};
有向图Class(摘要):
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 studio17\community\vc\tools\msvc.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++ 的新手,到目前为止,我正在尝试理解这些令人筋疲力尽的错误消息。我真的陷入了这个,它真的毫无意义。我在下面分享的代码是我正在处理的个人有向图头文件的一部分。我不会分享所有内容,因为它有点长,而且其他部分似乎与我的问题无关。但如果需要请说明,我会分享。现在下面的函数是评估一个顶点(即节点)是否可以从给定的根顶点到达。它采用迭代定义的深度优先搜索来执行此操作。
代码编译但我在运行时不断收到此错误消息,这根本没有意义,因为它似乎是由于将 int 推入 std::stack 引起的(当我注释掉我所做的行时这,代码运行)。这样 it->first 就是一个 int。它是我的邻接列表中的一个索引,类型为 std::unordered_map,也代表一个顶点 ID。
到目前为止,我尝试了两种不同的方法。我将 it->first 分配给一个单独的 int id 变量并尝试以这种方式推送它。我尝试将 std::stack 更改为 std::stack
我正在使用 Visual Studio 2017 和 MSVC 编译器。
顶点Class:
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; }
};
有向图Class(摘要):
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 studio17\community\vc\tools\msvc.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
模式下不运行时,代码可能会突然开始运行,因为编译器不再生成此验证码,但它也可能会破坏您的内存并崩溃以奇怪的方式。
错误很明显:代码比较来自不同容器对象的迭代器。迭代器必须来自同一个容器对象。