关于子函数中用new的问题

开始的时候 代码是这样的

#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;
}


想用create1函数建立一个树,将root1指针传入,自认为没问题的,结果如下图。


发现子函数中的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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值