我编写了一个Dll,里面封装了dxut等图形库,dll对外提供了一些函数获取变量。我用了两种类型程序去链接它测试使用,一种是DOS控制台EXE,一种是标准的MFC单文档应用程序。这两种程序对该dll的使用基本相同,并且没有用到DXUT相关功能。结果发现前者没有问题,MFC程序则有内存泄漏。
    好,现在开始找内存泄漏。我先用简单的_CrtSetBreakAlloc函数对内存分配定位,发现这些泄漏并非常规的释放问题,都是在一些类内部的共享static变量上,甚至有些内存分配号太靠前,_CrtSetBreakAlloc也定位不了。
    接着我把该dll改成静态链接库直接链进exe,发现一切正常,没有任何泄漏。怪了,于是大查互联网和CSDN,在大家的推荐下用BC查,BC显示没有内存泄漏(memory leaks),但是有Other leaks,显示有一些Resource Leak,大部分还是和静态变量有关,我试着修改了一些静态变量,减少了一些Resource Leak,但是最后VC的Debug info窗口仍然显示有泄漏。
    如果用上了DXUT,那VC会打出更多的内存泄漏,这些改成用静态链接库就都没事。另外我这里也不存在多进程或者多线程访问dll共享变量数据的问题。
    我看了一下DXUT的代码,里面有大量的静态变量、静态函数,并且也加载其他dll。
    我能作的就这么多了,忘高手指点,感激不尽!内存泄漏Debug输出例:
Dumping objects ->
{119} normal block at 0x01086130, 4 bytes long.
 Data: <    > 00 00 00 00

解决方案 »

  1.   

    我用BC测试了一下静态链接库编译的版本,仍然是那些Resource Leak,看来这些Resource Leak和VC Debug 输出的内存泄漏dump是没有关系的!
        到底这些内存泄漏发生在哪里呢?大家有没有遇到过类似情况?
      

  2.   

    说老实话,我半年前就遇到这个问题,当时在CSDN上也问了,但没有解决根本问题。后来就一直用静态链接库一直到现在,什么问题都没有。到了现在需要出SDK了,最好提供给用户dll啊,但是却有内存泄漏,虽然程序完全正常,但人人看着肯定都郁闷。
      

  3.   

    目前的情况是:我强制_CrtSetBreakAlloc在所有静态变量创建之前执行,于是终于发现了一个地方。DXUTgui.h中有定义在CDXUTIMEEditBox类内部的CUniBuffer类共享静态变量,这样在链接进进程空间的时候,即使没有用DXUTgui相关功能,该静态变量仍然是要创建的。我发现在CUniBuffer类的构造函数中有个new WCHAR[]的内存分配操作,虽然我跟踪程序发现在其析构函数也被正确调用并做了相应的delete操作,但是Debug的Dumping objects仍然显示它为内存泄漏的地址!
        我试着将CDXUTIMEEditBox中的CUniBuffer类型静态变量改成全局变量,该问题仍然存在。
      

  4.   

    目前的进展:
        在国外的一个网站上有人回到:The memory leak detection was removed from the code because it displayed far too many false positives. The so called "leaks" are most likely static variables that are not deallocated at the time the program ends. They are not leaks, per se, just blocks of memory that stay allocated for the duration of the program. They are used, but they never get deallocated, and hence are seen as "leaks" by the detector.
       强!老外太直接了当了!
       于是我试着修改DXUT文件,我将DXUTenum.cpp中的DXUTGetEnumeration()进行了修改,将其中的CD3DEnumeration类型局部静态变量改为动态创建的内存变量,并且为DXUT增加了一个新函数提供该变量的删除操作。至此,整个DXUT“假内存泄漏问题”解决,成功地将整个DXUT进行了dll封装。
       我用的DirectX SDK版本为Microsoft DirectX 9.0 SDK (Update April 2005),不知道大家遇到过类似问题没有,有没有更好的办法解决!