У меня проблема с моей программой. Для небольшого числа ребер он работает отлично, но когда он получает 15000 ребер ориентированного графика, я получаю ошибку сегментации после одной минуты выполнения. Отладчик говорит, что он вызывается векторным методом push_back. Кто-нибудь из вас знает, что не так с кодом и как его избежать?std :: vector :: push_back throws segmentation fault
Ошибка в процедуре 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;
}
}
}
Цель для меня с моей программой, чтобы найти путь в ориентированном графе, где каждое ребро используется только один раз.
Разве вы не можете сузить его? –
Вам не следует обращаться к векторам, используя 'graph [i]'. Гораздо безопаснее использовать 'graph.at (i)', так как это проверяет, что граф достаточно большой, и в первую очередь генерирует исключение. Опасность с '[i]' заключается в том, что он может попытаться получить доступ за пределы массива и испортить вашу память, что даст вам ошибку seg или аналогичную. Некоторые могут попытаться утверждать, что '.at (i)' медленнее, но игнорировать их :-) В реальной программе ваш профиль обычно подтверждает, что это незначительно. Перед оптимизацией сосредоточьтесь на правильности. –
@Aaron: Индексирование вне границ - это ошибка программирования, то есть ошибка. Использование '.at()' вместо 'operator []' не исправляет ошибку, она просто делает ее явно различной. Совет должен быть на самом деле _fix_ ошибка, а не просто бросать исключение, когда ошибка встречается. – ildjarn