从我们写代码说起
C++面试常见的一个问题是:new与malloc的区别,然后你去网上搜索这个问题,常见回答如下:
malloc : 只能单独给对象申请空间,不能进行构造函数的调用
new : 不仅能申请动态空间,还能调用构造函数进行对成员变量初始化
我们此篇文章对哪一块源码分析呢?对,就是对new的分配内存的那部分源码进行分析。::operator new这是一个重载,重载的功能就只是分配内存,而调用构造函数在分配后的内存进行初始化,那是编译器的工作。而既有分配内存,又能在内存处初始化的功能叫做new operator。
源码分析
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
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
上面这个就是operator new,主要就是调用一个malloc,若调用不成功,调用_callnewh
extern "C" int __cdecl _callnewh(size_t size)
{
{
_PNH pnh = (_PNH) DecodePointer(_pnhHeap);
if ( (pnh == NULL) || ((*pnh)(size) == 0) )
return 0;
}
return 1;
}
_pnhHeap是我们在_set_new_handler函数里面EncodePointer进来的。然后调用一下我们自己的new失败处理函数。回到malloc。malloc函数里又调用了_nh_malloc_dbg
extern "C" void * __cdecl _nh_malloc_dbg (
size_t nSize,
int nhFlag,
int nBlockUse,
const char * szFileName,
int nLine
)
{
int errno_tmp = 0;
void * pvBlk = _nh_malloc_dbg_impl(nSize, nhFlag, nBlockUse, szFileName, nLine, &errno_tmp);
if ( pvBlk == NULL && errno_tmp != 0 && _errno())
{
errno = errno_tmp; // recall, #define errno *_errno()
}
return pvBlk;
}
extern "C" st