实现 DFS 在较短的输入下工作正常,但在较大的输入下会抛出分段错误



我正在编写的这段代码是为了检测图中的SCC,它是"斯坦福图和数据结构"的第一个编程任务,但是,对于大量输入,它会抛出异常错误。我已经在不同的 IDE 上尝试过它,并且一直遇到较大输入的分段错误。 我真的很想找出问题以及如何解决这个问题,如果这是问题所在,我愿意改变我的方法。 我几乎可以肯定这可能是由于动态存储的填充。 这是代码:

#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
#include<fstream>
#define lli long long int
#define usi unsigned short int
using namespace std;
struct node {
vector<int> edge_index;
bool detected;
int leader;
};
vector<node> nodes;
vector<pair<int, int>> edges;
map<int, vector<int>> SCC;
vector<int> finish_time, SCC_size;
int count_t, lead;
bool rev = false;
void DFS(int start) {
//int size = nodes.size();
nodes[start].detected = true;
static int c = 0;
c++;
//int size1 = nodes.size();
for (int i = 0; i < nodes[start].edge_index.size(); i++) {
if (!rev) {
if (edges[nodes[start].edge_index[i]].first == start && !nodes[edges[nodes[start].edge_index[i]].second].detected) {
nodes[edges[nodes[start].edge_index[i]].second].leader = lead;
DFS(edges[nodes[start].edge_index[i]].second);
}
}
else if (edges[nodes[start].edge_index[i]].second == start && !nodes[edges[nodes[start].edge_index[i]].first].detected)
DFS(edges[nodes[start].edge_index[i]].first);
}
if (rev)
finish_time[count_t++] = start;
c--;
}
bool comp(int a, int b) {
return a > b;
}
void DFS_loop() {
for (auto&& i : nodes)
i.detected = false;
count_t = 0;
//lli extra[10000];
finish_time.resize(nodes.size() - 1);
for (int i = 1; i < nodes.size(); i++) {
if (!nodes[i].detected) {
lead = i;
rev = true;
DFS(i);
}
}
for (auto&& i : nodes)
i.detected = false;
rev = false;
for (int i = (signed int)finish_time.size() - 1; i >= 0; i--) {
if (!nodes[finish_time[i]].detected) {
nodes[finish_time[i]].leader = finish_time[i];
lead = finish_time[i];
DFS(finish_time[i]);
}
}
for (int i = 1; i < nodes.size(); i++)
SCC[nodes[i].leader].push_back(i);
map<int, vector<int>>::iterator itr;
for (itr = SCC.begin(); itr != SCC.end(); itr++) {
SCC_size.push_back(itr->second.size());
}
}
int main() {
ifstream file;
file.open("SCC.txt");
file.seekg(0);
if (file.is_open()) {
while (true) {
int temp, temp1;
file >> temp >> temp1;
if (!file)
break;
if (nodes.size() <= max(temp, temp1))
nodes.resize((int)max(temp, temp1) + 1);
edges.emplace_back(temp, temp1);
nodes[temp].edge_index.push_back(edges.size() - 1);
nodes[temp1].edge_index.push_back(edges.size() - 1);
}
}
else {
cout << "ERROR OPENING FILE";
return -1;
}
file.clear();
cout << "File Storing finishedn";
DFS_loop();
sort(SCC_size.begin(), SCC_size.end(), comp);
for (int i = 0; i < 5 && i < SCC_size.size(); i++)
cout << SCC_size[i] << " ";
cout << endl;
map<int, vector<int>>::iterator itr;
/*for(itr = SCC.begin(); itr != SCC.end(); itr++){
cout << itr->first << ": ";
for(int i : itr->second)
cout << i << " ";
cout << endl;
}*/
}

这里有一个例外: SCC.exe 中0x00311287时未处理的异常:0xC00000FD:堆栈溢出(参数:0x00000001、0x00602FE0(。

异常清楚地说明了原因 -堆栈溢出

代码中的递归DFS例程可能被调用了足够的次数以超过可用的堆栈大小(或者可能是无限的,如 @Ulrich 所建议的那样(。

可以在此处找到一些处理此问题的建议(如何处理或避免C++中的堆栈溢出(,但此类问题的一般建议是切换到迭代解决方案(例如。DFS 使用 std::stack(。

最新更新