如何创建指针链?我想创建 objects,它有指向进一步 objects 的指针,它有指针。这可能吗?
How to create pointer chains? I would like to create objects that have pointers pointing to further objects, that has pointers. Is this even possible?
我已经创建了这个示例代码,但我就是无法让它工作。我想从 parent 节点创建 children,每个 children 都有一个 parent,并且每个节点都有一个指向其 parent 的指针。第一个 parent 的指针是空指针。现在的问题是,如果我在树枝末端的某个地方,我如何return一步步到第一个parent,并写出历史?
为了简单起见,在此示例中,我创建了一个具有一条简单路径的线性图。
我发现如果我想第二次取消引用一个节点的 parent 节点,我已经得到了假结果,而且我无法比第一次 parent 更进一步。所以我只能解引用当前节点的parent。这是为什么?我已经看到人们在 linked-lists 中存储每个指针,但我想避免这种情况。目标是,每个节点都存储在一个 list<Node>
中,并且每个节点只存储其 parents 指针,因此我们可以从每个节点追溯到第一个 parent。
#include <iostream>
#include <list>
using namespace std;
struct Node
{
int node;
Node *parent;
};
void create (Node parent, list<Node>& graph)
{
if (graph.size() < 10)
{
Node nn;
nn.node = parent.node+1;
nn.parent = &parent;
graph.push_back(nn);
create(nn, graph);
}
}
int main()
{
list<Node> graph;
Node parent;
parent.node = 0;
parent.parent = nullptr;
graph.push_back(parent);
create(parent, graph);
for (auto i : graph)
{
cout << i.node << " ";
}
cout << endl << endl;
auto it = graph.begin();
advance(it, 3);
cout << (*it).node << endl;
cout << (*(*(*it).parent).parent).node;
return 0;
}
您正在创建 Node
作为 create
函数中的局部变量。当您退出函数的范围时,您保存为 Node
s' parent
的地址将不包含以前存在的 Node
(每个 nn.parent
变成 dangling pointer ).
如果你想在一个函数中创建 Node
s,它应该看起来像这样:
void create(Node* parent, list<Node>& graph)
{
if (graph.size() < 10)
{
Node* nn = new Node;
nn->node = parent->node + 1;
nn->parent = parent;
graph.push_back(*nn);
create(nn, graph);
}
}
然而,这会导致几个问题:
- 在这一行
graph.push_back(*nn);
中,我们正在取消引用 nn
,这会导致不必要地复制 int
和 Node*
(结构属性)值。
- 我们造成了内存泄漏,因为我们没有在任何地方保存
nn
值,所以我们以后不能删除它的内容。
最好保留 Node*
的列表而不是 Node
:
list<Node*> graph;
这样,我们就可以遍历列表并稍后删除动态分配的 Node
s:
for (auto i : graph)
delete i;
而不是复制 int
和 Node*
值,我们只是将 Node* nn
推到列表中:
graph.push_back(nn);
Note that it
is a pointer to a pointer now, so it would require double dereferencing:
cout << (**it).node << endl;
cout << (*(*(**it).parent).parent).node;
我已经创建了这个示例代码,但我就是无法让它工作。我想从 parent 节点创建 children,每个 children 都有一个 parent,并且每个节点都有一个指向其 parent 的指针。第一个 parent 的指针是空指针。现在的问题是,如果我在树枝末端的某个地方,我如何return一步步到第一个parent,并写出历史?
为了简单起见,在此示例中,我创建了一个具有一条简单路径的线性图。
我发现如果我想第二次取消引用一个节点的 parent 节点,我已经得到了假结果,而且我无法比第一次 parent 更进一步。所以我只能解引用当前节点的parent。这是为什么?我已经看到人们在 linked-lists 中存储每个指针,但我想避免这种情况。目标是,每个节点都存储在一个 list<Node>
中,并且每个节点只存储其 parents 指针,因此我们可以从每个节点追溯到第一个 parent。
#include <iostream>
#include <list>
using namespace std;
struct Node
{
int node;
Node *parent;
};
void create (Node parent, list<Node>& graph)
{
if (graph.size() < 10)
{
Node nn;
nn.node = parent.node+1;
nn.parent = &parent;
graph.push_back(nn);
create(nn, graph);
}
}
int main()
{
list<Node> graph;
Node parent;
parent.node = 0;
parent.parent = nullptr;
graph.push_back(parent);
create(parent, graph);
for (auto i : graph)
{
cout << i.node << " ";
}
cout << endl << endl;
auto it = graph.begin();
advance(it, 3);
cout << (*it).node << endl;
cout << (*(*(*it).parent).parent).node;
return 0;
}
您正在创建 Node
作为 create
函数中的局部变量。当您退出函数的范围时,您保存为 Node
s' parent
的地址将不包含以前存在的 Node
(每个 nn.parent
变成 dangling pointer ).
如果你想在一个函数中创建 Node
s,它应该看起来像这样:
void create(Node* parent, list<Node>& graph)
{
if (graph.size() < 10)
{
Node* nn = new Node;
nn->node = parent->node + 1;
nn->parent = parent;
graph.push_back(*nn);
create(nn, graph);
}
}
然而,这会导致几个问题:
- 在这一行
graph.push_back(*nn);
中,我们正在取消引用nn
,这会导致不必要地复制int
和Node*
(结构属性)值。 - 我们造成了内存泄漏,因为我们没有在任何地方保存
nn
值,所以我们以后不能删除它的内容。
最好保留 Node*
的列表而不是 Node
:
list<Node*> graph;
这样,我们就可以遍历列表并稍后删除动态分配的 Node
s:
for (auto i : graph)
delete i;
而不是复制 int
和 Node*
值,我们只是将 Node* nn
推到列表中:
graph.push_back(nn);
Note that
it
is a pointer to a pointer now, so it would require double dereferencing:cout << (**it).node << endl; cout << (*(*(**it).parent).parent).node;