new操作符内部原理(二) 及 delete和free

前面我们说了new在分配空间的一些细节,这里作一些补充。其实我们在调用new时,在他的地层重载运算符里面是这样实现的:

void *p;
 while ((p = malloc(size)) == 0)
  if (_callnewh(size) == 0)
   _STD _Nomemory();
 return (p);

 

可以看出它是直接调用了我们C语言中常用的malloc函数来实现。由此我们可以知道malloc也同样会分配一个块头。32Byte + dataSize + 4( 0xfdfdfdfd )这么大的一个空间。

 

我们再来看看delete,它的实现是:

_CrtMemBlockHeader * pHead;

        RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

        if (pUserData == NULL)
            return;

        _mlock(_HEAP_LOCK);  /* block other threads */
        __TRY

            /* get a pointer to memory block header */
            pHead = pHdr(pUserData);

             /* verify block type */
            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

            _free_dbg( pUserData, pHead->nBlockUse );

        __FINALLY
            _munlock(_HEAP_LOCK);  /* release other threads */
        __END_TRY_FINALLY

        return;

 

这里我们注意到一点,在第一个用红色字体显示的if里面是检查了UserData是否为空。所以我们便又得出一个结论:delete某个指针的时候,在delete之前我们是不用去检查这个指针是否为空的。通常我们都会这样写:

 if ( p != NULL )

    delete p;

 

当然这里的习惯是好的,但是我们得清楚这里的空判断是可以不要的。

 

我们再看看下边一句红色的部分调用的是_free_dbg, 由此我们又想到了C语言中常用的free。于是我们看看free的实现,我们知道了,在free里面它是直接调用了_free_dbg,这里我们又得想到,free没有去检查UserData是否为空,直接就进行释放 - -。。。我们就必须得这么写了:

 if ( p != NULL )

    free( p );

 

在之后就进行了一系列的检查,这里面处理块头两指针类似一个链表,操作是这样的:

 

if (pHead->pBlockHeaderNext)
            {
                pHead->pBlockHeaderNext->pBlockHeaderPrev = pHead->pBlockHeaderPrev;
            }
            else
            {
                _ASSERTE(_pLastBlock == pHead);
                _pLastBlock = pHead->pBlockHeaderPrev;
            }

            if (pHead->pBlockHeaderPrev)
            {
                pHead->pBlockHeaderPrev->pBlockHeaderNext = pHead->pBlockHeaderNext;
            }
            else
            {
                _ASSERTE(_pFirstBlock == pHead);
                _pFirstBlock = pHead->pBlockHeaderNext;
            }

 

这样就移除了当前要释放的内存块结点。很容易看出跟链表删除结点是一样的。。

之后的操作就是:

memset( pHead, _bDeadLandFill,
                sizeof( _CrtMemBlockHeader ) + pHead->nDataSize + nNoMansLandSize );

 

清空当前分配块的整个空间,蓝色的字体的定义是:static unsigned char _bDeadLandFill = 0xDD

以0xDD来填充。之后就是一些收尾工作。。。大致就到这里就给释放掉了 - -

所以呢,new和malloc, delete和free他们的联系是很紧密的。也是为了C++兼容C的吧。。

说的有什么不对的地方望大家多多指教。。。。

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值