I'm trying to store a map of VALUE
to Node*
but after each addEdge
, the value for the added keys (Node*
) changes.
One example is if I call addEdge(u, v)
, the map shows all the data correctly within the lifetime. If another call is made to addEdge(u, w)
, the keys u, v
are present but the values are "corrupted"? Here's an example of the output:
Sample code:
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;
}
I've tried calling nodes.emplace
after assigning next, prev
but it didn't fix it. Thanks!
EDIT Updated 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);
}
CodePudding user response:
Your initial addEdge
was taking the address of unnamed temporary objects, which is not valid C .
Your updated addEdge
has nodes point to the leaked Node
s that you new
, not the Node
s that are in the map.
You don't have to test for presence in the map, map::emplace
doesn't overwrite existing items, and the return value holds a reference to the Node
with that key.
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;
}