Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向结构的指针向量的元素具有相同的地址_C++_Data Structures_Recursive Datastructures_Disjoint Sets - Fatal编程技术网

C++ 指向结构的指针向量的元素具有相同的地址

C++ 指向结构的指针向量的元素具有相同的地址,c++,data-structures,recursive-datastructures,disjoint-sets,C++,Data Structures,Recursive Datastructures,Disjoint Sets,我试图实现一个不相交的森林数据结构。简言之,它是一种没有公共元素的集合数据结构,可以轻松执行诸如组合2个集合和查找元素集合等操作。每个集合都有一定数量的元素 我将集合实现为树,集合中的每个元素都是节点类型。这是我的DisjointForesh.h文件: #ifndef STD_VECTOR #define STD_VECTOR #include <vector> #endif #ifndef DISJOINTFOREST_DISJOINTFOREST_H #define DISJO

我试图实现一个不相交的森林数据结构。简言之,它是一种没有公共元素的集合数据结构,可以轻松执行诸如组合2个集合和查找元素集合等操作。每个集合都有一定数量的元素

我将集合实现为树,集合中的每个元素都是节点类型。这是我的DisjointForesh.h文件:

#ifndef STD_VECTOR
#define STD_VECTOR
#include <vector>
#endif

#ifndef DISJOINTFOREST_DISJOINTFOREST_H
#define DISJOINTFOREST_DISJOINTFOREST_H

struct TreeRoot;

struct Node{
    int rank = 0;
    int id;
    TreeRoot* parentTree;
    Node* parent;
    int value;
};

struct TreeRoot{
    std::vector<Node *> nodes;
    int id;
};

TreeRoot makeSet(int x);
.......

#endif //DISJOINTFOREST_DISJOINTFOREST_H
如你所见:

每个节点值都是一个垃圾值 每个节点都有相同的地址 父ID为0,但应与节点值相同 我不明白为什么会发生上述三种情况。我期待的值为0至7和不同的地址为每个节点。我是相对新的C++,因此,我发现很难调试这个程序。 你能帮我找出哪里出了问题吗?任何优化我的代码的建议都会很有帮助。如果需要其他信息,请告诉我

TreeRoot makeSet(int x){
    TreeRoot tree;
    Node node;
    node.value = x;
    node.parent = &node;
    tree.nodes.push_back(&node);
    tree.id = node.value;
    node.parentTree = &tree;
    return tree;
}
节点是该for函数块的本地节点,具有自动存储功能。在函数结束时,节点的生存期结束,节点将自动销毁

返回的树指向此已销毁的节点。一旦函数返回,这些指针就会失效

for(Node *node: nodes){
    std::cout << node->value << "-->" << node->parentTree->id << '\n';

在这里,您可以通过无效指针间接访问不存在的对象。程序的行为未定义。

您正在节点向量中推送相同的节点*节点,因此,您将获得相同的地址和值。makeSet返回一个TreeRoot,其数据成员指向本地范围的节点,而不是随后超出范围的其他对象。这是未定义的行为。@G.M.您的意思是在创建TreeRoot后立即清除TreeRoot中的节点变量吗?为include添加自定义include guard没有多大意义。每个标准标题都应该已经有一个。@MohitMotwani阅读了您最喜欢的新标题。从更简单的数据结构开始,比如链表。从你上面的回答和评论中,我了解到我的代码有许多超出范围的错误、纠错指针等。你知道我如何从现在开始修复我的代码吗?我真的不知道如何使我的对象不被删除。@MohitMotwani使用std::set或std::unordered_set怎么样?你说得对,我可以使用这个。但是我相信实现这些将有助于我更好地理解C++,因为这是我的主要目标,而不是使用标准库中的结构。你可能需要一本书。猜测不是学习语言的最佳策略。谢谢@eerorika。我会记住的。目前参考learncpp.com。
Total trees: 8
Total nodes: 8
Printing all nodes with parent trees:
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
-749254164-->0
0x7ffe0cd60cf0
TreeRoot makeSet(int x){
    TreeRoot tree;
    Node node;
    node.value = x;
    node.parent = &node;
    tree.nodes.push_back(&node);
    tree.id = node.value;
    node.parentTree = &tree;
    return tree;
}
for(Node *node: nodes){
    std::cout << node->value << "-->" << node->parentTree->id << '\n';