标签:定义类 博客 void 为我 方式 poi 应对 区域 一个
内存区域:在c++中我们用心的关键字 new、delete完成对空间的申请和释放。语法是也是定义一个指针变量接受开辟的地址,int p=new int;c++允许我们对申请的空间初始化,只要在后面跟上(),()内为要初始化的内容即可。同时也可以用int p=new int[];的方式申请连续的内存空间,这种方式在释放时的方式为delete [] p;。
注意:在申请自定义类型时new和malloc是类似的,那么意味着对于内置类型free和delete是可以混合使用的,用new申请的空间用free释放也不会出现什么错误,而对于用户自定义类型new和delete会分别调用构造函数和析构函数,而malloc和free则不会,malloc申请的是与对象大小相同的一块内存空间,是不会构成对象的,所以我们在申请和释放空间时要注意配对!
我们在这里谈谈malloc的原理:我们知道malloc申请大小为10个字节的空间时系统会为我们申请大于十个字节的空间,大概申请来的空间是长这个样子滴:
这也就是我们在free的时候系统会知道free多少个字节,因为在这个类似于结构体的结构内最前面已经保存了我们申请空间大小的数值了。
这两个函数是new和delete在底层调用的函数,也就是这两个函数为我们完成了内存的开辟和释放。
我们首先看看operator new这个函数:
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
// try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{
// report no memory
// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
从这个函数我们可以看到底层也是通过malloc实现的,那么malloc申请成功则直接返回,malloc申请失败尝试执行空间不足的应对措施,执行这个措施就会继续申请,否则抛出异常。所以new函数一般都不会申请失败。
我们再来看operator delete这个函数:
void operator delete(void *pUserData)
{
_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;
}
通过这个我们知道底层也是通过free实现的就ok。
我们再看看对于自定义类型new和delete的原理:
new的原理
最后的最后我们再细谈一下malloc和new的区别:
1.new是操作符、malloc是函数
2.new可以完成对开辟空间的初始化、malloc则不能
3.malloc在使用时需要计算所开辟内存的大小(字节)并传递,而new只需跟上类型即可
4.malloc的返回值是void,所以要强制类型转化,new后是类型则不需要。
5.malloc申请失败会返回NULL,所以要进行判空,new不需要但需要捕获异常
6.malloc和free不会调用构造和析构函数。
标签:定义类 博客 void 为我 方式 poi 应对 区域 一个
原文地址:https://blog.51cto.com/14239789/2441364