一、crt new实现方法
new——>全局operator new(afxmem.h)——>_malloc_dbg(crtdbg.h)——>_heap_alloc_dbg_impl(dbgheap.h
此处生成了debug头,mfc内存泄露检测就是使用此cookie)——>_heap_alloc_base(malloc.h)
_heap_alloc_base代码如下:
_forceinline void * __cdecl _heap_alloc (size_t size)
{
if (_crtheap == 0) {
_FF_MSGBANNER(); /* write run-time error banner */
_NMSG_WRITE(_RT_CRT_NOTINIT); /* write message */
__crtExitProcess(255); /* normally _exit(255) */
}
if (__active_heap == __SYSTEM_HEAP) {
return HeapAlloc(_crtheap, 0, size ? size : 1);
} else
if ( __active_heap == __V6_HEAP ) {
if (pvReturn = V6_HeapAlloc(size)) {
return pvReturn;
}
}
#ifdef CRTDLL
else if ( __active_heap == __V5_HEAP )
{
if (pvReturn = V5_HeapAlloc(size)) {
return pvReturn;
}
}
#endif /* CRTDLL */
if (size == 0)
size = 1;
size = (size + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1);
return HeapAlloc(_crtheap, 0, size);
}其中_crtheap在Dll附加到进程调用__DllMainCRTStartup——>_CRT_INIT——>_heap_init代码如下:
int __cdecl _heap_init (
int mtflag
)
{
#if defined _M_AMD64 || defined _M_IA64
// HEAP_NO_SERIALIZE is incompatible with the LFH heap
mtflag = 1;
#endif /* defined _M_AMD64 || defined _M_IA64 */
// Initialize the "big-block" heap first.
if ( (_crtheap = HeapCreate( mtflag ? 0 : HEAP_NO_SERIALIZE,
BYTES_PER_PAGE, 0 )) == NULL )
return 0;
#ifndef _WIN64
// Pick a heap, any heap
__active_heap = __heap_select();//默认为system_heap
if ( __active_heap == __V6_HEAP )
{
// Initialize the small-block heap
if (__sbh_heap_init(MAX_ALLOC_DATA_SIZE) == 0)
{
HeapDestroy(_crtheap);
_crtheap=NULL;
return 0;
}
}
#ifdef CRTDLL
else if ( __active_heap == __V5_HEAP )
{
if ( __old_sbh_new_region() == NULL )
{
HeapDestroy( _crtheap );
_crtheap=NULL;
return 0;
}
}
#endif /* CRTDLL */
#elif defined _M_AMD64 || defined _M_IA64
{
// Enable the Low Fragmentation Heap for AMD64 and IA64 by default
// It's the 8 byte overhead heap, and has generally better
// performance charateristics than the 16 byte overhead heap,
// particularly for apps that perform lots of small allocations
ULONG HeapType = 2;
HeapSetInformation(_crtheap, HeapCompatibilityInformation,
&HeapType, sizeof(HeapType));
}
#endif /* defined _M_AMD64 || defined _M_IA64 */
return 1;
}二、Dll导出函数返回string和动态内存陷阱
由1可知,当dll以静态链接的方式(MT)使用时,dll中得string和动态内存是在dll的堆中分配的。所以必须在dll中释放。当以动态链接crt时,所有dll都共用crt dll(MD),分配和释放都在同一个堆上。
备注:string有默认16字节的小内存,当字符串大小小于16字节时不会动态分配内存。
4505

被折叠的 条评论
为什么被折叠?



