IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    指针指针

    Yukang (moorekang@gmail.com)发表于 2010-07-20 00:00:00
    love 0

    今天由一个函数加深了对指针的理解,是这么一个函数:

    void BST_Delete(BITREE y) //删除节点y
    {
        if (y->lch==NULL && y->rch==NULL && y->p)
        {
            if(y==(y->p)->lch) (y->p)->lch=NULL;
            else (y->p)->rch=NULL;
        }
        else if (y->rch==NULL && y->p)
        {
            if(y==y->p->lch) y->p->lch=y->lch;
            else y->p->rch=y->lch;
        }
        else if (y->lch==NULL && y->p){
            if(y==y->p->lch) y->p->lch=y->rch;
            else y->p->rch=y->rch;
        }
        else    {
            BITREE t=BST_Successor(y);
            y->data=t->data;
            BST_Delete(t);
            y=t;//y=NULL
    
        }
        free(y);
    }

    在最后一个else内,如果二叉搜索树中有左右孩子,那么找这个删除节点的后继,把内容互换,然后删除后继 节点,因为后继节点一定只有一个孩子或者没有孩子。最后只有一个free()操作其实是为了代码简洁,可以把前面每一个else if后面加一个free, 最后不写free()操作。但是这么写运行起来会有问题,y=t,就是所指向的地址相同,但是因为是 递归操作,t指向的地址在调用BST_Delete(t)的时候已经被free掉了,所以如果再删除一次就会 出现内存错误,修改方法是y=NULL,或者修改函数参数,用指针引用的形式 void BST_Delete( BITREE& y),然后再在free(y)后面增加一句y=NULL。以前以为两次调用free(p)是不会出现问题的,free()在释放掉p指向的内存以后,会 自动将p赋值为NULL,其实没有这部分操作。

    前些天还看到一个面试题目,malloc申请的空间用delete删除会有什么问题?一般来说没有问题, 内存会释放掉,而且即使是有析构函数的对象指针,用delete删除的时候同样会调用析构函数。这说明 c++的delete操作其实是在c的基础增加了一些操作,先调用析构函数,然后释放空间。良好的编程风格 就是free/malloc,new/delete一一对应,甚至不要出现一次调用,多次释放,像上面那样的因为递归 而产生的多次释放并不是很好发现



沪ICP备19023445号-2号
友情链接