我编写了一个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
好,现在开始找内存泄漏。我先用简单的_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
到底这些内存泄漏发生在哪里呢?大家有没有遇到过类似情况?
我试着将CDXUTIMEEditBox中的CUniBuffer类型静态变量改成全局变量,该问题仍然存在。
在国外的一个网站上有人回到: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),不知道大家遇到过类似问题没有,有没有更好的办法解决!