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

本文深入探讨了C++中的new和C语言中的malloc之间的关系,分析了new和delete的底层实现,并对比了C语言中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的吧。。

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值