我试图用更简单的代码(如下所示)在我更复杂的代码中重现一个问题,该代码创建一个树并分配键,然后遍历树并打印出键。
该程序的输出应该是:
This key is 3
This key is 1
但是它给出了
This key is 3
This key is 33603600
这让我觉得我错误地创建了我的树结构。任何人都可以指出我的错误并希望批评我创建这种树结构的方式吗?
node.h:
1 #ifndef _NODE_H_
2 #define _NODE_H_
3
4 class node {
5
6 public:
7 node();
8 void assign(int keyval);
9 int key();
10 node* gt();
11 node* lt();
12
13 private:
14 node* _lt;
15 node* _gt;
16 int _key;
17 };
18
19 // traverse the tree
20 void traverse(node* pnode);
21
22 #endif
node.cpp:
1 #include "node.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 using namespace std;
6
7 // default constructor
8 node::node() {
9 printf("Constructing node!\n");
10 // start off as a leaf which returns no class
11 _lt = NULL;
12 _gt = NULL;
13 _key = -1;
14 }
15
16 // assign this key and create new nodes (if possible)
17 void node::assign(int key) {
18 printf("assigning key = %i!\n", key);
19
20 _key = key;
21
22 if(_key < 0) {
23 return;
24 }
25 int key_lt = key-4;
26 int key_gt = key-2;
27 printf("key_lt = %i\n", key_lt);
28 printf("key_gt = %i\n", key_gt);
29 if( key_lt > 0) {
30 node lt_node;
31 lt_node.assign(key_lt);
32 _lt = <_node;
33 }
34 if( key_gt > 0) {
35 node gt_node;
36 gt_node.assign(key_gt);
37 _gt = >_node;
38 }
39 }
40
41 // simple return functions
42 int node::key() {
43 return _key;
44 }
45 node* node::gt() {
46 return _gt;
47 }
48 node* node::lt() {
49 return _lt;
50 }
51
52 // traverse a node
53 void traverse(node* pnode)
54 {
55 ///// same things!
56 //printf("This key is %i\n", (*pnode).key());
57 //printf("This key is %i\n", pnode->key());
58 printf("This key is %i\n", pnode->key());
59
60 if(pnode->gt() != NULL) {
61 pnode = pnode->gt();
62 traverse( pnode );
63 }
64
65 }
最后,主要例程:
1 #include "node.h"
2
3 #include <stdio.h>
4
5 using namespace std;
6
7 int main(int argc, char** argv) {
8
9 node* root = new node();
10
11 int key = 3;
12 root->assign(key);
13
14 traverse(root);
15 }
答案 0 :(得分:3)
问题在于如何在lt
中创建gt
和node::assign()
节点。您正在堆栈上创建它们,因此一旦执行离开创建它们的范围,对象将被销毁。
您应该在堆上分配它们(使用new
,就像在main()
中一样,并在node
析构函数中删除它们。最好是,如果您使用的是支持C +的编译器+11,您可以考虑使用智能指针(例如unique_ptr
和shared_ptr
),这样节点将在不再使用时被销毁。
此外,root
中的main()
永远不会被销毁。您应该在调用traverse()
(或使用智能指针)后删除它。至少在您的示例代码中,没有必要使用new
进行分配,因为它仅在main()
内使用。