开始的时候 代码是这样的
#include<iostream>
using namespace std;
class tnode
{
public:
tnode(int i):value(i){}
int value;
tnode *left;
tnode *right;
};
void PreOrderTraverse(tnode *root)
{
cout << root->value << " ";
if(root->left != NULL)
PreOrderTraverse(root->left);
if(root->right != NULL)
PreOrderTraverse(root->right);
}
void creat1(tnode *root1)
{
//cout << &root1 << endl;
root1=new tnode(5);
root1->left = new tnode(3);
root1->right = new tnode(7);
root1->left->left = new tnode(4);
root1->left->right = new tnode(8);
root1->right->left = new tnode(2);
root1->right->right = new tnode(9);
PreOrderTraverse(root1);
cout << endl;
//return root1;
}
int main()
{
tnode *root1;
//cout << &root1 << endl;
creat1(root1);
PreOrderTraverse(root1);
cout << endl;
tnode *root2=new tnode(5);
root2->left = new tnode(3);
root2->right = new tnode(7);
PreOrderTraverse(root2);
cout << endl;
}
发现子函数中的PreOrderTraverse(root1);顺利执行了,而main函数里的PreOrderTraverse(root1);失败。。
寻找原因,找到这篇博文 关于在子函数中调用new开辟内存空间
http://blog.sina.com.cn/s/blog_6e543e450100qn4n.html
上面的博文中提到当调用CreateArr函数时,根据实参与形参原理,此时CreateArr函数会用一个形参a来代替arr,然后开辟一个相应的内存空间,但当CreateArr函数返回时,形参a即被消毁,但由于new申请的空间位于堆,并不会随着函数退栈而一起被消毁,所以先间开辟的那片内存还在,但成了一片无法访问的死区。而arr仍然未能得到赋值。
想到 cout << root1 << endl; 结果子函数和mian函数中打印出的一样,
然后想到cout << &root1 << endl; root1中存的是一个地址,这个地址的值是一样的,但是两个root1 很有可能不是同一个(形参和实参),形参在子函数结束后会被销毁,所以这两个root1 可能不是同一个(不在同一个内存单元中),int a = int b =1; 值一样但是不是同一个数。
果然。。。。
仔细想,找到博文的最后一句,还是没办法理解。。自己认为,形参销毁后,建立的树变成了死区(在子函数内),也销毁了,main里面的root1 指向了一段被销毁的内存。。
怎么改?把形参return回来就好了
#include<iostream>
using namespace std;
class tnode
{
public:
tnode(int i):value(i){}
int value;
tnode *left;
tnode *right;
};
void PreOrderTraverse(tnode *root)
{
cout << root->value << " ";
if(root->left != NULL)
PreOrderTraverse(root->left);
if(root->right != NULL)
PreOrderTraverse(root->right);
}
tnode* creat1(tnode *root1)
{
cout << &root1 << endl;
root1=new tnode(5);
root1->left = new tnode(3);
root1->right = new tnode(7);
root1->left->left = new tnode(4);
root1->left->right = new tnode(8);
root1->right->left = new tnode(2);
root1->right->right = new tnode(9);
PreOrderTraverse(root1);
cout << endl;
return root1;
}
int main()
{
tnode *root1;
cout << &root1 << endl;
root1 = creat1(root1);
PreOrderTraverse(root1);
cout << endl;
tnode *root2=new tnode(5);
root2->left = new tnode(3);
root2->right = new tnode(7);
PreOrderTraverse(root2);
cout << endl;
}
over