函数完成后用作映射值的指针损坏
Pointers used as values in map corrupted after function finishes
我正在尝试将 VALUE
的映射存储到 Node*
,但在每个 addEdge
之后,添加的键 (Node*
) 的值都会发生变化。
一个例子是如果我调用addEdge(u, v)
,地图会正确显示生命周期内的所有数据。如果对 addEdge(u, w)
进行另一个调用,键 u, v
存在但值“已损坏”?下面是一个输出示例:
示例代码:
struct Node {
VALUE value;
Node* prev;
Node* next;
};
class Graph {
std::map<VALUE, Node*> nodes;
};
void Graph::addEdge(VALUE u, VALUE v) {
Node* uNode;
Node* vNode;
if (nodes.count(u) == 0) {
uNode = &Node{ u, nullptr, nullptr };
nodes.emplace(u, uNode);
} else {
uNode = nodes.at(u);
}
if (nodes.count(v) == 0) {
vNode = &Node{ v, nullptr, nullptr };
nodes.emplace(v, vNode);
} else {
vNode = nodes.at(v);
}
uNode->next = vNode;
vNode->prev = uNode;
}
我尝试在分配 next, prev
后调用 nodes.emplace
,但没有解决问题。谢谢!
编辑
更新了 addEdge:
void addEdgeVALUE u, VALUE v) {
Node* uNode;
Node* vNode;
bool isUNodePresent = true;
bool isVNodePresent = true;
if (nodes.count(u) == 0) {
isUNodePresent = false;
uNode = new Node(u, nullptr, nullptr);
} else {
uNode = &nodes.at(u);
}
if (nodes.count(v) == 0) {
isVNodePresent = false;
vNode = new Node(v, nullptr, nullptr);
} else {
vNode = &nodes.at(v);
}
uNode->next = vNode;
vNode->prev = uNode;
if (!isUNodePresent) nodes.emplace(u, *uNode);
if (!isVNodePresent) nodes.emplace(v, *vNode);
}
您的初始 addEdge
使用未命名临时对象的地址,这在 C++ 中是无效的。
您更新后的 addEdge
的节点指向您 new
泄漏的 Node
,而不是地图中的 Node
。
您不必测试地图中的存在,map::emplace
不会覆盖现有项目,并且 return 值包含对 Node
的引用关键。
struct Node {
VALUE value;
Node* prev;
Node* next;
};
class Graph {
std::map<VALUE, Node> nodes;
public:
void addEdge(VALUE u, VALUE v);
};
void Graph::addEdge(VALUE u, VALUE v) {
Node & uNode = nodes.emplace(u, { u }).first->second;
Node & vNode = nodes.emplace(v, { v }).first->second;
uNode.next = &vNode;
vNode.prev = &uNode;
}
我正在尝试将 VALUE
的映射存储到 Node*
,但在每个 addEdge
之后,添加的键 (Node*
) 的值都会发生变化。
一个例子是如果我调用addEdge(u, v)
,地图会正确显示生命周期内的所有数据。如果对 addEdge(u, w)
进行另一个调用,键 u, v
存在但值“已损坏”?下面是一个输出示例:
示例代码:
struct Node {
VALUE value;
Node* prev;
Node* next;
};
class Graph {
std::map<VALUE, Node*> nodes;
};
void Graph::addEdge(VALUE u, VALUE v) {
Node* uNode;
Node* vNode;
if (nodes.count(u) == 0) {
uNode = &Node{ u, nullptr, nullptr };
nodes.emplace(u, uNode);
} else {
uNode = nodes.at(u);
}
if (nodes.count(v) == 0) {
vNode = &Node{ v, nullptr, nullptr };
nodes.emplace(v, vNode);
} else {
vNode = nodes.at(v);
}
uNode->next = vNode;
vNode->prev = uNode;
}
我尝试在分配 next, prev
后调用 nodes.emplace
,但没有解决问题。谢谢!
编辑 更新了 addEdge:
void addEdgeVALUE u, VALUE v) {
Node* uNode;
Node* vNode;
bool isUNodePresent = true;
bool isVNodePresent = true;
if (nodes.count(u) == 0) {
isUNodePresent = false;
uNode = new Node(u, nullptr, nullptr);
} else {
uNode = &nodes.at(u);
}
if (nodes.count(v) == 0) {
isVNodePresent = false;
vNode = new Node(v, nullptr, nullptr);
} else {
vNode = &nodes.at(v);
}
uNode->next = vNode;
vNode->prev = uNode;
if (!isUNodePresent) nodes.emplace(u, *uNode);
if (!isVNodePresent) nodes.emplace(v, *vNode);
}
您的初始 addEdge
使用未命名临时对象的地址,这在 C++ 中是无效的。
您更新后的 addEdge
的节点指向您 new
泄漏的 Node
,而不是地图中的 Node
。
您不必测试地图中的存在,map::emplace
不会覆盖现有项目,并且 return 值包含对 Node
的引用关键。
struct Node {
VALUE value;
Node* prev;
Node* next;
};
class Graph {
std::map<VALUE, Node> nodes;
public:
void addEdge(VALUE u, VALUE v);
};
void Graph::addEdge(VALUE u, VALUE v) {
Node & uNode = nodes.emplace(u, { u }).first->second;
Node & vNode = nodes.emplace(v, { v }).first->second;
uNode.next = &vNode;
vNode.prev = &uNode;
}