提问人:Blargian 提问时间:3/8/2023 更新时间:3/8/2023 访问量:88
使用 push_back 添加指向空 std::list 的指针的正确方法
Correct way to add a pointer to an empty std::list using push_back
问:
我有两个简单的类,分别表示连接图结构中的节点和边。
//node.h
#include "edge.h"
#include <string>
#include <list>
#include <utility>
using namespace std;
class Edge;
class Node {
private:
list<Edge> edgeList;
string nodeName;
pair <int, int> coordinates;
public:
Node();
void setXY(int x, int y);
void insertEdge(Edge& edgeToAdd);
void removeEdge(Edge& edgeToAdd);
list<Edge> getEdgeList();
};
在 node.cpp 中实现的方法如下:insertEdge
void Node::insertEdge(Edge& edgeToAdd) {
this->edgeList.push_back(edgeToAdd);
}
该类是在 edge.h 中声明的另一个简单类:Edge
#pragma once
#include "node.h"
class Node;
class Edge {
private:
Node* destinationNode;
int edgeWeight;
public:
//constructor
Edge(Node* destNode, int w);
//Setters and Getters
void setDestinationNode(Node* destNode);
void setEdgeWeight(int weight);
Node* getDestinationNode();
int getEdgeWeight();
};
在我编写单元测试的另一个文件中,我尝试使用上面详述的方法插入指向边缘对象的指针:insertEdge
SECTION("an edge gets inserted to the adjacency list")
{
Node* b = &Node();
Edge* e = new Edge(b,1);
b->insertEdge(*e);
list<Edge> edgelist = b->getEdgeList();
}
我已确定由于非法内存访问而导致分段错误。通过单步执行代码,我可以看到被非法访问的变量是 std::list 的分配器的成员。我怀疑我的问题与我的声明方式有关edgeList.push_back(edgeToAdd)
_Prev
_Next
std::list<Edge*> edgeList
我的问题是,将指针添加到仅声明的 std::list 的正确方法是什么?
答:
1赞
user253751
3/8/2023
#1
正确的方法就是你做的方式。
但是,这一行:
Node* b = &Node();
创建一个新的,获取其地址,然后销毁该节点,因为它只是一个临时对象。然后,您访问已销毁的 .Node
Node
您可能想编写然后使用 instead of - 这会创建一个局部变量,该变量在函数结束之前保持活动状态。Node b;
b.
b->
Node
评论
0赞
Blargian
3/8/2023
谢谢,解决了问题。我正在尝试在这里做一个图的邻接列表实现,所以我最初想到的是将指针存储在边缘列表中的节点。出于某种原因,我认为不制作副本而是使用指针或引用更有效。但是,如果 Node 对象只会在函数结束之前保持活动状态,我认为最好将 Nodes 的副本存储在边缘列表中?
0赞
user253751
3/8/2023
@Blargian要在边缘列表中存储节点的副本?(这是否包括其边缘列表的副本,包括边缘列表的副本,包括其他节点的副本的副本?永远持续下去?创建无限副本?)如果没有,你到底想做什么?
评论
Node* b = &Node();
不应编译,它会获取临时对象的地址,该临时对象的地址在完整表达式结束时立即超出范围。std::list
std::vector
list
In that case the memory would be allocated on the heap and not get released as soon as the full expression ends
Edge* e = new Edge(b, 1); b->insertEdge(*e);
没有理由在这里动态分配你的。您正在将其副本插入 的 ,因此您不妨只使用具有自动存储持续时间的本地。Edge
Node
edgeList