내 프로그램에 문제가 있습니다. 작은 수의 가장자리에 대해서는 완벽하게 작동하지만 방향 그래프의 가장자리가 15000 개가되면 1 분 런타임 후에 세그먼트 오류가 발생합니다. 디버거는 벡터 푸시 백 메소드에 의해 throw됩니다. 누군가가 코드에 무엇이 잘못되었는지, 어떻게 피하는 지 알고 있습니까?std :: vector :: push_back이 세그먼트 화 오류를 throw합니다.
result.push_back (tmpResult)에서 dfs 프로 시저에 오류가 발생했습니다.는
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
typedef struct {
unsigned int endNode; // Number of dest node
bool used; // true, if edge was used in dfs
} EdgeType;
typedef struct {
unsigned int startNode; // Number of source node
vector<EdgeType> edge; // Outgoing edges from node
} NodeType;
typedef struct {
unsigned int startNode;
unsigned int endNode;
} ResultType;
bool loadInput(vector<NodeType>& graph, unsigned int& numEdges);
void dfs(vector<NodeType>& graph, unsigned int i, unsigned int numEdges, vector<ResultType>& result);
int main(int argc, char** argv) {
vector<NodeType> graph;
vector<ResultType> result;
unsigned int numEdges;
result.reserve(300000);
// Generate oriented multigraph (3 nodes, 150000 edges)
numEdges = 150000;
NodeType tmpNode;
EdgeType tmpEdge;
for (unsigned int i = 0; i < 50000; i++) {
tmpEdge.used = false;
tmpEdge.endNode = 1;
tmpNode.edge.push_back(tmpEdge);
}
tmpNode.startNode = 0;
graph.push_back(tmpNode);
tmpNode.edge.clear();
for (unsigned int i = 0; i < 50000; i++) {
tmpEdge.used = false;
tmpEdge.endNode = 2;
tmpNode.edge.push_back(tmpEdge);
}
tmpNode.startNode = 1;
graph.push_back(tmpNode);
tmpNode.edge.clear();
for (unsigned int i = 0; i < 50000; i++) {
tmpEdge.used = false;
tmpEdge.endNode = 0;
tmpNode.edge.push_back(tmpEdge);
}
tmpNode.startNode = 2;
graph.push_back(tmpNode);
tmpNode.edge.clear();
cout << "numEdges: " << numEdges << endl;
// Find way
for (unsigned int i = 0; i < graph.size(); i++) {
dfs(graph, i, numEdges, result);
}
// No way found
cout << "-1" << endl;
return 0;
}
void dfs(vector<NodeType>& graph, unsigned int i, unsigned int numEdges, vector<ResultType>& result) {
// Way was found, print it and exit program (bad style, only for testing)
if (numEdges == result.size()) {
cout << graph.size() << endl;
vector<ResultType>::iterator it;
for (it = result.begin(); it != result.end(); it++) {
cout << (*it).startNode << " " << (*it).endNode << endl;
}
cout << "0 0" << endl;
exit(0);
}
// For each outgoing edge do recursion
for (unsigned int j = 0; j < graph[i].edge.size(); j++) {
if (i >= graph.size()) return;
if (!graph[i].edge[j].used) {
graph[i].edge[j].used = true;
ResultType tmpResult;
tmpResult.startNode = graph[i].startNode;
tmpResult.endNode = graph[i].edge[j].endNode;
result.push_back(tmpResult);
dfs(graph, graph[i].edge[j].endNode, numEdges, result);
result.pop_back();
graph[i].edge[j].used = false;
}
}
}
내 프로그램 나를 위해 목표는 각 에지는 한 번만 사용 중심의 그래프에서 방법을 찾아야하는 것입니다.
좁힐 수 없습니까? –
'graph [i]'를 사용하여 벡터에 접근해서는 안됩니다. 'graph.at (i)'를 사용하는 것이 훨씬 안전합니다. 왜냐하면 그래프가 충분히 크고 지금은 예외를 던질 것이기 때문입니다. '[i]'의 위험은 배열의 범위를 벗어나 액세스하려고 시도하고 메모리가 손상되어 seg 결함 또는 유사한 오류를 일으킬 수 있다는 것입니다. 어떤 이들은'.at (i)'가 더 느리지 만 무시할 것이라고 주장하려고 시도 할 수도 있습니다 :-) 실제 프로그램에서 여러분의 프로파일은 대개 무시할 만하다는 것을 확인합니다. 최적화하기 전에 정확성에 집중하십시오. –
@Aaron : 범위를 벗어난 색인 생성은 프로그래밍 오류, 즉 버그입니다. 'operator []'대신'.at()'를 사용하면 버그가 수정되지 않고 단지 다르게 나타납니다. 조언은 실제로 버그가 _fix_되어야하며, 버그가 발생했을 때 예외를 throw하지 않아야합니다. – ildjarn