Reputation: 119
i have the following issue.
typedef std::pair<VertexT,CostT> LocalEdgeT;
typedef std::vector<LocalEdgeT> NeighborT;
typedef std::size_t VertexT;
typedef double CostT;
virtual const NeighborT& getNeighbors( VertexT v) const override
{
std::vector<LocalEdgeT> neighbors;
//here I'm adding elements, not important for the question
return neighbors;
}
I can not make the function return NeighborT without reference, because I have to use a function that's given to me from my university, that requires the reference for some reason.
But when I return it with the following call in main:
std::vector<NeighborT> test = Object.getNeighbors(arg);
It gives a segmentation fault, probably because I'm returning reference to a local variable. Any idea how I can fix it, that it still returns the vector by reference and it works with my function call in the main method? Furthermore I have to compile with c++11 standard.
Some additional information:
I just put in "Object" because i thought it isn't that important for the question. Im my case the function getNeighbors is a member of a Graph class, which has a certain number of Vertices and a vector for all Edges from Vertex a to Vertex b. The function getNeighbors should now find to a given Vertex v all neighbors. To have a own vector for every Vertex in the class is (from my point of view) not recommended. I do have a map, where I save all Edges, with its double "CostT" to go that edge. Here is the full class.
typedef std::size_t VertexT;
typedef std::pair<VertexT,VertexT> EdgeT;
typedef double CostT;
class DistanceGraph
{
public:
typedef std::pair<VertexT,CostT> LocalEdgeT;
typedef std::vector<LocalEdgeT> NeighborT;
protected:
std::size_t vertexCount;
public:
DistanceGraph( int num_verts= 0)
: vertexCount(num_verts) {}
virtual ~DistanceGraph() {}
std::size_t numVertices() const { return vertexCount; }
virtual const NeighborT& getNeighbors( VertexT v) const = 0;
virtual CostT estimatedCost( VertexT from, VertexT to) const = 0;
virtual CostT cost( VertexT from, VertexT to) const = 0;
};
class CoordinateGraph : public DistanceGraph {
public:
std::map< EdgeT, CostT > allEdges;
std::vector < std::pair < double, double > > geometricPosition;
void setNumVertices( size_t);
friend std::istream& operator >> (std::istream& in,CoordinateGraph& g);
virtual const NeighborT& getNeighbors( VertexT v) const override
{
std::vector<LocalEdgeT> neighbors;
for(size_t i = 0; i < (*this).numVertices(); i++)
{
EdgeT edge = std::make_pair(v,i);
if((*this).allEdges.find(edge) != (*this).allEdges.end())
{
neighbors.push_back( std::make_pair(i,(*this).allEdges.find(edge) -> second));
}
}
return neighbors;
}
virtual CostT cost( VertexT from, VertexT to) const override
{
EdgeT edge = std::make_pair(from,to);
if((*this).allEdges.find(edge) != (*this).allEdges.end()) return (*this).allEdges.find(edge) -> second;
else return 10000000;
}
};
To clarify this again, I can NOT make the function getNeighbors return NeighborT. One solution I see, is to make the neighbors of every Vertex a classmember stored in a vector. The above code obviously has a problem with the return of a local variable, when I call the function like above stated.
Upvotes: 0
Views: 297
Reputation: 1161
since you seem to have the hard requirement to return the vector of neighbors by reference, you basically have no choice and have to store it in your class.
just make a std::map<VertexT, NeighborT>
class member to store them.
on call of getNeighbors
check for a existing entry and return either the existing or create a new one and add it to the map.
Upvotes: 2
Reputation: 49028
What you can do is make neighbors
thread local and clear it on each invocation of the function, that way, you get the same semantics of static without the expensive initialization, assuming you're not multi-threading of course.
virtual const NeighborT& getNeighbors( VertexT v) const override
{
thread_local std::vector<LocalEdgeT> neighbors;
neighbors.clear();
// stuff...
return neighbors;
}
Upvotes: 2