【发布时间】:2020-11-14 01:39:20
【问题描述】:
我正在学习 C++。作为映射项目的一部分,我试图(反向)通过节点类中的父地址指针属性从特定节点到起始节点的链表遍历。我试图弄清楚为什么父母的地址值一直被破坏,这会导致错误并阻止遍历。
我提取了下面项目的基本组件,以及一些帮助代码,可以轻松地重新创建错误。
#include <iostream>
#include <stdio.h>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
class Node
{
public:
int idx;
Node * addr = nullptr;
Node * parent_addr = nullptr;
Node (int init_idx, Node * init_parent) {
idx = init_idx;
parent_addr = init_parent;
}
};
void PrintNode(Node & n) {
cout << "idx: " << n.idx << " addr: " << n.addr << " parent_addr: " << n.parent_addr << endl;
}
void PrintNodeList (vector<Node> & path) {
for (Node n : path) {PrintNode(n);}
}
void CreateNodeList (const int node_count, vector<Node> & node_list) {
for (int i=0; i<=(node_count - 1); i++) {
if (i==0) {
// first node parent is null
node_list.push_back(Node(i, nullptr));
} else {
// subsequent nodes parent is previous node
node_list.push_back(Node(i, &node_list[i-1]));
}
// store address of node to clearly follow forward and reverse traversals
node_list[i].addr = &node_list[i];
}
cout << "Node List..." << endl;
PrintNodeList(node_list);
}
void TraverseNodeList(Node * current_node) {
cout << endl << "Traversing node list in reverse..." << endl;
while (current_node != nullptr) {
PrintNode(*current_node);
current_node = current_node->parent_addr;
}
cout << endl << "Completed reverse traversal." << endl;
}
int main() {
// generate list of nodes
const int node_count = 5;
vector<Node> node_list;
CreateNodeList (node_count, node_list);
// reverse traverse the list of nodes
const int last_node = node_count - 1;
TraverseNodeList(&node_list[last_node]);
return 0;
}
Here is a sample node list (node index, address of the node, address of node's parent):
Here is a traversal corrupting at the start node:
Here is a traversal corrupting before the start node:
实际的 CreateNodeList 函数:
此代码是从 A* 搜索项目中提取的。随着地图的遍历,正在检查的节点(current_node)的邻居被更新(父属性被设置并且它们被标记为已访问)并通过以下方式推送到std::vector<node *> node_list:
for (auto neighbor : current_node->neighbors) {
neighbor->parent = current_node;
node_list.push_back(neighbor);
neighbor->visited = true;
}
【问题讨论】:
-
你怎么知道是
parent_addr被破坏了,而不是addr?如果您想保持this->addr等于this,那么缺少复制构造函数是有问题的。 (为什么你甚至存储addr而不是获取对象的地址?) -
在定义
node_list和第一次调用node_list.push_back之间的一段时间内调用node_list.reserve(5)会有所不同吗? -
重新检查
push_back的文档,然后仔细检查CreateNodeList看是否能发现问题。 -
Vorian,SamV 实际上给出了正确的答案,所以我删除了我的。建议你接受前者。
标签: c++ memory corruption