抛出 C++ 异常
C++ exception thrown
我正在学习 C++,并且已经浪费了很多时间来尝试解决我遇到的错误的原因。
当我 运行 下面的代码时,我抛出了一个异常。它发生在程序结束时,所以我相信它与边缘指针有关:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct Edge {
int src, dest;
};
class Graph {
public:
int V, E;
Edge *edge = new Edge[E * sizeof(Edge)];
Graph(int Ver, int Edg);
};
Graph::Graph(int Ver, int Edg) {
V = Ver;
E = Edg;
}
Graph* createGraph(int V, int E) {
Graph* graph = new Graph(V,E);
return graph;
}
int find(int* parents, int val) {
if (parents[val] == -1)
return val;
return find(parents, parents[val]);
}
void Union(int *parents, int x, int y) {
parents[x] = y;
}
int isCycle(Graph* graph) {
int* parents = new int[graph->V * sizeof(int)];
memset(parents, -1, graph->V * sizeof(int));
for (int i = 0; i < graph->E; i++) {
int x = find(parents, graph->edge[i].src);
int y = find(parents, graph->edge[i].dest);
if (x == y) {
return 1;
};
Union(parents, x, y);
}
return 0;
}
int main()
{
int V = 9, E = 8;
Graph* graph = createGraph(V, E);
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[6].src = 0;
graph->edge[6].dest = 6;
graph->edge[5].src = 0;
graph->edge[5].dest = 7;
graph->edge[1].src = 1;
graph->edge[1].dest = 2;
graph->edge[2].src = 3;
graph->edge[2].dest = 2;
graph->edge[3].src = 4;
graph->edge[3].dest = 3;
graph->edge[4].src = 4;
graph->edge[4].dest = 5;
graph->edge[7].src = 5;
graph->edge[7].dest = 7;
if (isCycle(graph))
cout << "graph contains cycle";
else
cout << "graph doesn't contain cycle";
return 0;
}
我几个月前才开始学习 C++,有人可以帮助我理解为什么会出现该异常吗?
Edge *edge = new Edge[E * sizeof(Edge)];
除非 E
被初始化,这会将未初始化的变量乘以 sizeof(Edge)
(这在表面上也是错误的,但我们稍后会谈到)。这是未定义的行为。
Graph::Graph(int Ver, int Edg) {
V = Ver;
E = Edg;
}
这还不够好。 class 成员的默认值(如果指定)用于在 构造函数主体开始 运行 之前初始化它们 。
正确的做法是使用构造函数的初始化部分:
Graph::Graph(int Ver, int Edg) : V{Ver}, E{Ver}
{
}
这会首先初始化 V
和 E
,所以现在:
Edge *edge = new Edge[E * sizeof(Edge)];
所以在这里,E
现在已经初始化,解决了这个问题。但这仍然有些不正确。很明显,根据其余代码,这实际上应该是:
Edge *edge = new Edge[E];
在 C++ 中,当您希望声明一个包含 4 个整数的数组时,您所要做的就是声明:
int n[4];
编译器负责将 4 乘以容纳 int
所需的字节数。 new
语句也是如此。如果您的目标是构建一个包含 #E
Edge
的数组,那么不出所料:new Edge[E]
。同样的错误在显示的代码中多次出现。
我正在学习 C++,并且已经浪费了很多时间来尝试解决我遇到的错误的原因。 当我 运行 下面的代码时,我抛出了一个异常。它发生在程序结束时,所以我相信它与边缘指针有关:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct Edge {
int src, dest;
};
class Graph {
public:
int V, E;
Edge *edge = new Edge[E * sizeof(Edge)];
Graph(int Ver, int Edg);
};
Graph::Graph(int Ver, int Edg) {
V = Ver;
E = Edg;
}
Graph* createGraph(int V, int E) {
Graph* graph = new Graph(V,E);
return graph;
}
int find(int* parents, int val) {
if (parents[val] == -1)
return val;
return find(parents, parents[val]);
}
void Union(int *parents, int x, int y) {
parents[x] = y;
}
int isCycle(Graph* graph) {
int* parents = new int[graph->V * sizeof(int)];
memset(parents, -1, graph->V * sizeof(int));
for (int i = 0; i < graph->E; i++) {
int x = find(parents, graph->edge[i].src);
int y = find(parents, graph->edge[i].dest);
if (x == y) {
return 1;
};
Union(parents, x, y);
}
return 0;
}
int main()
{
int V = 9, E = 8;
Graph* graph = createGraph(V, E);
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[6].src = 0;
graph->edge[6].dest = 6;
graph->edge[5].src = 0;
graph->edge[5].dest = 7;
graph->edge[1].src = 1;
graph->edge[1].dest = 2;
graph->edge[2].src = 3;
graph->edge[2].dest = 2;
graph->edge[3].src = 4;
graph->edge[3].dest = 3;
graph->edge[4].src = 4;
graph->edge[4].dest = 5;
graph->edge[7].src = 5;
graph->edge[7].dest = 7;
if (isCycle(graph))
cout << "graph contains cycle";
else
cout << "graph doesn't contain cycle";
return 0;
}
我几个月前才开始学习 C++,有人可以帮助我理解为什么会出现该异常吗?
Edge *edge = new Edge[E * sizeof(Edge)];
除非 E
被初始化,这会将未初始化的变量乘以 sizeof(Edge)
(这在表面上也是错误的,但我们稍后会谈到)。这是未定义的行为。
Graph::Graph(int Ver, int Edg) {
V = Ver;
E = Edg;
}
这还不够好。 class 成员的默认值(如果指定)用于在 构造函数主体开始 运行 之前初始化它们 。
正确的做法是使用构造函数的初始化部分:
Graph::Graph(int Ver, int Edg) : V{Ver}, E{Ver}
{
}
这会首先初始化 V
和 E
,所以现在:
Edge *edge = new Edge[E * sizeof(Edge)];
所以在这里,E
现在已经初始化,解决了这个问题。但这仍然有些不正确。很明显,根据其余代码,这实际上应该是:
Edge *edge = new Edge[E];
在 C++ 中,当您希望声明一个包含 4 个整数的数组时,您所要做的就是声明:
int n[4];
编译器负责将 4 乘以容纳 int
所需的字节数。 new
语句也是如此。如果您的目标是构建一个包含 #E
Edge
的数组,那么不出所料:new Edge[E]
。同样的错误在显示的代码中多次出现。