登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[win32] crt heap 初探  

2009-04-18 09:35:00|  分类: win32 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

很多书上都说“谁分配,谁释放”,除了从设计哲学上保持代码的一致性外,我们从一个 .dll 分配,另一个 .dll 释放,其实也是有问题的。下面就来看看问题在哪。

下面是 vs2005 crt 中一个文件的节选,从中可以看到,malloc/free 其实就是调用了 HeapCreate/Alloc/Free 等 win32 API。注意:smalheap.c 文件只是起注释作用,实际的 malloc/free 的实现,参见 heapinit.c / malloc.c / free.c 等文件。

---------------------------------------- smalheap.c ------------------------------------------

HANDLE _crtheap=NULL;

/*
 * Primary heap routines (Initialization, termination, malloc and free).
 */

void __cdecl free (
        void * pblock
        )
{
        if ( pblock == NULL )
            return;

        HeapFree(_crtheap, 0, pblock);
}


int __cdecl _heap_init (
        int mtflag
        )
{
        if ( (_crtheap = HeapCreate( mtflag ? 0 : HEAP_NO_SERIALIZE,
                                     BYTES_PER_PAGE, 0 )) == NULL )
            return 0;

        return 1;
}


void __cdecl _heap_term (
        void
        )
{
        HeapDestroy( _crtheap );
        _crtheap=NULL;
}


void * __cdecl _nh_malloc (
        size_t size,
        int nhFlag
        )
{
        void * retp;

        for (;;) {

            retp = HeapAlloc( _crtheap, 0, size );

            /*
             * if successful allocation, return pointer to memory
             * if new handling turned off altogether, return NULL
             */

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

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

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


void * __cdecl malloc (
        size_t size
        )
{
        return _nh_malloc( size, _newmode );
}

------------------------------------- smalheap.c end ------------------------------------------

 

好了,我们来看看问题出在哪。如果都用 /MD dynamic-link crt,其实你用几个 DLL 都是没有问题的,相互之间混用 malloc/free 也不会挂。但 /MT 问题就来了:

a.exe + b.dll (两者都是 /MT static-link crt)

p = malloc(); // b.dll
free(p);      // a.exe

实际上相当于:
heap_b_dll = HeapCreate();
p = HeapAlloc(heap_b_dll);
HeapFree(heap_a_exe, p);

挂不挂,只是操作系统的问题,经测试。XP 没挂,而且 HeapFree 居然没有报错,而 Vista 就玩完了~
XP 虽然不报错,但肯定也是有问题的,咔咔。

结论很明了,还是书上说的“哪里分配,哪里释放”,使用 /MT dll 的同学,记得把某个类的 new/delete 都放到一个 DLL 里面管起来,就米问题了。另一个解法就是全部都用 /MT lib,所有东西全部打包到一个 .exe 里面啦。

当然,全部用 /MD 肯定是可以的

 

下面有篇抛砖引玉的文字,不错的说,不过解决问题还要靠自己查代码:
http://topic.csdn.net/u/20090104/09/f6801fcd-32c1-4e4f-b4c7-81fd6d27c82d.html


参考资料:
链接时如何选择C Run-Time(CRT) library, http://www.cppblog.com/aurain/archive/2008/04/23/47911.html
DLLs in Visual C++, http://msdn.microsoft.com/en-us/library/1ez7dh12
crt0.c/crtexe.c/crtdll.c/dllcrt0.c, http://www.cppblog.com/Violetrays/archive/2010/12/01/134077.html

  评论这张
 
阅读(1864)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018