new 最终是通过调用 malloc 来申请内存吗?

hns2002 2007-10-19 04:55:45
我知道new分2部分:

1、调用 void * operator new(size_t size);
2、调用类的构造函数。

在第一步里,operator new是调用的 malloc来申请内存吗?如果不是的话,是怎么申请内存的?

(我看到有些人说是,有些说不是,希望理解透彻的高手解释一下)。
...全文
638 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangqi187 2010-05-05
  • 打赏
  • 举报
回复
学习下 还没有结贴呢
hns2002 2007-10-22
  • 打赏
  • 举报
回复
嗯,大概明白了
icesorrow 2007-10-20
  • 打赏
  • 举报
回复
malloc/free只是从堆上分配和释放内存。
new/delete对于非元类型除了调用malloc/free分配和释放内存,还要调用构造和析构函数。
ttzzgg_80713 2007-10-20
  • 打赏
  • 举报
回复
yeah
hwman 2007-10-20
  • 打赏
  • 举报
回复
Further, it is unspecified whether new/delete is implemented in terms of malloc/free in a given implementation. It is specified, however, that malloc/free must not be implemented in terms of new/delete ...
=========================
进一步说,在一个给出的实现中没有规定要通过 malloc/free 的方式来实现 new/delete。然而,却规定了不能通过 new/delete 来实现 malloc/feee
不知道是不是这个意思,呵呵。如果翻译没有大错,就是说用不用都可以了
iambic 2007-10-19
  • 打赏
  • 举报
回复
《Exceptional C++》中的一段话:
Further, it is unspecified whether new/delete is implemented in terms of malloc/free in a given implementation. It is specified, however, that malloc/free must not be implemented in terms of new/delete ...
谁有兴趣可以翻下标准。我不熟得很。
ochinchina 2007-10-19
  • 打赏
  • 举报
回复
一般的C++的确省实现应该是调用malloc(), 但是开发者可以自己先申请一块大的内存,然后再大的内存中在申请一块小的内存, 这时的new就不是调用的malloc()了.
loops 2007-10-19
  • 打赏
  • 举报
回复
我上面说错了,release下,new和malloc都是呼叫了同一个函数,而且最后都调用了HeapAlloc函数。跟debug下的情况一样。
KingOfSco 2007-10-19
  • 打赏
  • 举报
回复
yes
Tuzki 2007-10-19
  • 打赏
  • 举报
回复
不了解,关注!
iambic 2007-10-19
  • 打赏
  • 举报
回复
记得C++标准对此有个交待——可惜我忘了结论……
回去可以找下。
loops 2007-10-19
  • 打赏
  • 举报
回复
ls贴的是Debug的代码,release下面,是直接调用kernel的HeapCreate的函数的,可以用ollydbg来看。
飞哥 2007-10-19
  • 打赏
  • 举报
回复
找new的实现代码就是了
看看这个

void * operator new( unsigned int cb )
{
return _nh_malloc( cb, 1 );
}



void * __cdecl _nh_malloc (
size_t nSize,
int nhFlag
)
{
return _nh_malloc_dbg(nSize, nhFlag, _NORMAL_BLOCK, NULL, 0);
}




void * __cdecl _nh_malloc_dbg (
size_t nSize,
int nhFlag,
int nBlockUse,
const char * szFileName,
int nLine
)
{
void * pvBlk;

for (;;)
{
/* lock the heap
*/
_mlock(_HEAP_LOCK);

/* do the allocation
*/
pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName, nLine);

/* unlock the heap
*/
_munlock(_HEAP_LOCK);

if (pvBlk || nhFlag == 0)
return pvBlk;

/* call installed new handler */
if (!_callnewh(nSize))
return NULL;

/* new handler was successful -- try to allocate again */
}
}




void * __cdecl _heap_alloc_dbg(
size_t nSize,
int nBlockUse,
const char * szFileName,
int nLine
)
{
long lRequest;
size_t blockSize;
int fIgnore = FALSE;
_CrtMemBlockHeader * pHead;

/* verify heap before allocation */
if (_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF)
_ASSERTE(_CrtCheckMemory());

lRequest = _lRequestCurr;

/* break into debugger at specific memory allocation */
if (lRequest == _crtBreakAlloc)
_CrtDbgBreak();

/* forced failure */
if (!(*_pfnAllocHook)(_HOOK_ALLOC, NULL, nSize, nBlockUse, lRequest, szFileName, nLine))
{
if (szFileName)
_RPT2(_CRT_WARN, "Client hook allocation failure at file %hs line %d.\n",
szFileName, nLine);
else
_RPT0(_CRT_WARN, "Client hook allocation failure.\n");

return NULL;
}

/* cannot ignore CRT allocations */
if (_BLOCK_TYPE(nBlockUse) != _CRT_BLOCK &&
!(_crtDbgFlag & _CRTDBG_ALLOC_MEM_DF))
fIgnore = TRUE;

/* Diagnostic memory allocation from this point on */

if (nSize > (size_t)_HEAP_MAXREQ ||
nSize + nNoMansLandSize + sizeof(_CrtMemBlockHeader) > (size_t)_HEAP_MAXREQ)
{
_RPT1(_CRT_ERROR, "Invalid allocation size: %u bytes.\n", nSize);
return NULL;
}

if (!_BLOCK_TYPE_IS_VALID(nBlockUse))
{
_RPT0(_CRT_ERROR, "Error: memory allocation: bad memory block type.\n");
}

blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;

#ifndef WINHEAP
/* round requested size */
blockSize = _ROUND2(blockSize, _GRANULARITY);
#endif /* WINHEAP */

pHead = (_CrtMemBlockHeader *)_heap_alloc_base(blockSize);

if (pHead == NULL)
return NULL;

/* commit allocation */
++_lRequestCurr;

if (fIgnore)
{
pHead->pBlockHeaderNext = NULL;
pHead->pBlockHeaderPrev = NULL;
pHead->szFileName = NULL;
pHead->nLine = IGNORE_LINE;
pHead->nDataSize = nSize;
pHead->nBlockUse = _IGNORE_BLOCK;
pHead->lRequest = IGNORE_REQ;
}
else {
/* keep track of total amount of memory allocated */
_lTotalAlloc += nSize;
_lCurAlloc += nSize;

if (_lCurAlloc > _lMaxAlloc)
_lMaxAlloc = _lCurAlloc;

if (_pFirstBlock)
_pFirstBlock->pBlockHeaderPrev = pHead;
else
_pLastBlock = pHead;

pHead->pBlockHeaderNext = _pFirstBlock;
pHead->pBlockHeaderPrev = NULL;
pHead->szFileName = (char *)szFileName;
pHead->nLine = nLine;
pHead->nDataSize = nSize;
pHead->nBlockUse = nBlockUse;
pHead->lRequest = lRequest;

/* link blocks together */
_pFirstBlock = pHead;
}

/* fill in gap before and after real block */
memset((void *)pHead->gap, _bNoMansLandFill, nNoMansLandSize);
memset((void *)(pbData(pHead) + nSize), _bNoMansLandFill, nNoMansLandSize);

/* fill data with silly value (but non-zero) */
memset((void *)pbData(pHead), _bCleanLandFill, nSize);

return (void *)pbData(pHead);
}




#define _heap_alloc_base _heap_alloc
/*

就这样一层一层调用下去的,最后调用到的都是类似于HeapAlloc,或者类似的在堆上分配空间的函数
*/
ckt 2007-10-19
  • 打赏
  • 举报
回复
Seu_why 2007-10-19
  • 打赏
  • 举报
回复
是malloc

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧