c++

c++ - ¿Puedo usar bucles anidados con vectores en cpp?



(1)

tengo un problema de cpp y no sé qué está mal ... tal vez puedas ayudarme :). Estoy tratando de implementar una estructura de datos para un gráfico. En este gráfico conectaré algunos nodos, que tienen una pequeña distancia euclidiana, pero en la segunda iteración, mi iterador apuntará a 0x0. Este caso aparece solo si doy la distancia de esos dos nodos a std :: cout. Aquí está mi código:

for(vector<Node*>::iterator n1 = g->getNodes().begin(); n1 != g->getNodes().end(); ++n1) { for(vector<Node*>::iterator n2 = g->getNodes().begin(); n2 != g->getNodes().end(); ++n2) { if(*n2 == 0) { // This will be entered after the first iteration of n2. cout << "n2 null" << endl; continue; } double distance = (*n1)->getDistance(*n2); // just euclidean distance if(distance <= minDistance) { // This works fine: cout << "(" << *n1 << "," << *n2 << ") << endl; // This brings me a "Segmentation fault" cout << "(" << *n1 << " , " << *n2 << ") -> " << distance << endl; } } }

¿Esto se debe a los bucles anidados? ¿Puede alguien decirme mi culpa? ¡Muchas gracias!

EDITAR: Aquí hay más código: node.h

#ifndef NODE_H_ #define NODE_H_ #include <vector> #include <iostream> #include <limits> #include <math.h> using namespace std; class Node { private: int x, y, z; public: Node(int x, int y, int z) : x(x), y(y), z(z) { } inline int getX() { return x; } inline int getY() { return y; } inline int getZ() { return z; } inline double getDistance(Node* other) { return sqrt(pow(x-other->getX(), 2) + pow(y-other->getY(), 2) + pow(z-other->getZ(), 2)); } }; #endif

graph.h

#ifndef GRAPH_H_ #define GRAPH_H_ #include <vector> #include "node.h" using namespace std; class Graph { private: vector<Node*> nodes; public: ~Graph() { while(!nodes.empty()) { delete nodes.back(), nodes.pop_back(); } } inline vector<Node*> getNodes() { return nodes; } inline int getCountNodes() { return nodes.size(); } bool createNode(int x, int y, int z) { nodes.push_back(new Node(x, y, z)); return true; }; #endif

main.cc

#include <iostream> #include <vector> #include <algorithm> #include <math.h> #include "model/graph.h" using namespace std; int main() { Graph *g = new Graph(); int nodeDistance = 100; for(int z = 0; z <= 300; z += nodeDistance) { for(int x = 0; x <= 500; x += nodeDistance) { for(int y = 0; y <= 300; y += nodeDistance) { g->createNode(x, y, z); } } } for(vector<Node*>::iterator n1 = g->getNodes().begin(); n1 != g->getNodes().end(); ++n1) { for(vector<Node*>::iterator n2 = g->getNodes().begin(); n2 != g->getNodes().end(); ++n2) { if(*n2 == 0) { // This will be entered after the first iteration of n2. cout << "n2 null" << endl; continue; } double distance = (*n1)->getDistance(*n2); // just euclidean distance if(distance <= nodeDistance) { // This works fine: cout << "(" << *n1 << "," << *n2 << ") << endl; // This brings me a "Segmentation fault" cout << "(" << *n1 << " , " << *n2 << ") -> " << distance << endl; } } } delete g; return 0; }


Un problema importante es que su función getNodes devuelve una copia de un vector, no el vector original. Por lo tanto, los iteradores que usa en los bucles no están iterando sobre el mismo vector.

En cambio, los iteradores que está utilizando en los bucles anidados están iterando sobre 4 vectores diferentes (pero equivalentes) en lugar del vector real del objeto en cuestión.

No hay nada malo en devolver una copia de un vector en general. Sin embargo, cuando haga esto, debe asegurarse de llamar a dicha función si realmente desea una copia , y no el mismo vector. Usar la función getNodes como la usó no es un uso válido en términos de lo que está tratando de lograr.

El error está aquí:

inline vector<Node*> getNodes() { return nodes; }

La solución:

inline vector<Node*>& getNodes() { return nodes; }

Este último asegura que se devuelva una referencia al vector real en cuestión, no una copia del vector real. Puede agregar una función adicional que devuelva el vector como una copia si aún desea tener la funcionalidad disponible.