我的程序有問題。對於少量的邊緣它可以很好地工作,但是當它獲得15000個方向圖的邊緣時,我會在運行一分鐘後出現分段錯誤。調試器說它是由vector_back_back方法拋出的。是否有人知道代碼有什麼問題,以及如何避免它?std :: vector :: push_back拋出分段錯誤
dfs程序在行result.push_back(tmpResult)中拋出錯誤;
#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;
}
}
}
與我的計劃,我的目標是要找到在面向圖形,其中每個邊緣只使用一次的方式。
難道你不能縮小它嗎? – 2012-01-06 16:13:01
你不應該使用'graph [i]'來訪問向量。使用'graph.at(i)'更安全,因爲這將檢查圖形是否足夠大,如果現在會引發異常。 '[i]'的危險在於它可能會嘗試訪問超出數組邊界並損壞你的內存,給你一個seg錯誤或類似的錯誤。有些人可能會試圖爭辯說'.at(i)'較慢,但忽略它們:-)在真實世界的程序中,您的配置文件通常會確認這是微不足道的。優化前關注正確性。 – 2012-01-06 16:23:16
@Aaron:索引超出範圍是一個編程錯誤,即一個錯誤。使用'.at()'而不是'operator []'不能修復這個bug,它只是使它變得不同。建議應該是實際修復bug,而不是在遇到bug時拋出異常。 – ildjarn 2012-01-06 16:25:18