【发布时间】:2018-06-16 19:21:09
【问题描述】:
我有以下问题。
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;
}
我不能让函数在没有引用的情况下返回 NeighborT,因为我必须使用我大学给我的函数,由于某种原因需要引用。
但是当我在 main 中通过以下调用返回它时:
std::vector<NeighborT> test = Object.getNeighbors(arg);
它给出了分段错误,可能是因为我正在返回对局部变量的引用。知道如何修复它,它仍然通过引用返回向量,并且它与我在 main 方法中的函数调用一起工作吗? 此外,我必须使用 c++11 标准进行编译。
一些附加信息:
我只是输入了“对象”,因为我认为它对这个问题并不重要。在我的情况下,函数 getNeighbors 是 Graph 类的成员,它具有一定数量的顶点和从顶点 a 到顶点 b 的所有边的向量。函数 getNeighbors 现在应该找到给定顶点 v 所有邻居。 (从我的角度来看)不建议为类中的每个 Vertex 拥有一个自己的向量。 我确实有一张地图,我保存所有的边缘,它的双“CostT”去那个边缘。 这是完整的课程。
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;
}
};
为了再次澄清这一点,我不能让函数 getNeighbors 返回 NeighborT。 我看到的一个解决方案是使每个 Vertex 的邻居成为存储在向量中的类成员。 当我调用上述函数时,上面的代码显然有返回局部变量的问题。
【问题讨论】:
-
您正在返回对在函数返回之前释放的局部变量 (
neighbors) 的引用。免费后使用是UB。 -
您是否发布了所有相关代码?
Object是什么? -
测试例程只是由 Testname(Graph) 调用。我目前没有测试例程的代码。但是只有 NeighborT 测试例程会出现分段错误,现在由于某种原因可以通过 thread_local 关键字解决。
-
如果需要引用返回,函数返回时变量必须是“活的”。这意味着变量必须是 a)“类成员”或 b)它必须是“静态或 thread_local”(这可能不是您想要的)或 c)分配有
new(这将是一个非常糟糕的设计) .我有一种感觉,您最终陷入这种情况是因为您未发布的某些代码中的设计选择错误。 -
这个问题需要minimal reproducible example;原始海报给了我们几乎可以肯定被误解的一组约束。这导致了对 OP 真正问题的错误回答。正确的答案可能只是对约束的误解,或者返回一个类局部变量,或者完全是其他的东西。