dll中的内存分配调试

最近终于把每次程序退出的时候,一大堆的内存泄露LOG的问题解决了。
在说这个问题之前,先分析一下DLL中的内存分配,说到DLL的内存分配,先说说windowsDLL编译。
在VS上编译的时候,有MT,MD之分,后面再加个D指的是debug版本。那么这两个版本,有什么区别。区别是,MT会把windows下的运行时依赖的库,静态的联编到DLL中,而MD是动态的连接。那么这两个会导致的区别就是,MT编的DLL会自己内存分配的地空间,MD则是和被调用的EXE公用内存分配的地址空间。所以MD方式编译的DLL是优先选择,因为你的DLL可能也会依赖其他的DLL,如果大家有的是MD,有的是MT,太混乱了,并且对于内存管理很不利,比方,DLL不能操作EXE空间的,EXE不能操作DLL里面。
但是,问题是我的DLL就是MD,怎么还是会泄露呢。并且,我审查代码,DLL里面没有NEW这样的操作,相当于是,所有的变量要么是全局或者局部。然后我就翻到了DLL的加载的相关代码。

#ifdef CRTDLL
void __cdecl _initterm (
#else  /* CRTDLL */
static void __cdecl _initterm (
#endif  /* CRTDLL */
        _PVFV * pfbegin,
        _PVFV * pfend
        )
{
        /*
         * walk the table of function pointers from the bottom up, until
         * the end is encountered.  Do not skip the first entry.  The initial
         * value of pfbegin points to the first valid entry.  Do not try to
         * execute what pfend points to.  Only entries before pfend are valid.
         */
        while ( pfbegin < pfend )
        {
            /*
             * if current table entry is non-NULL, call thru it.
             */
            if ( *pfbegin != NULL )
                (**pfbegin)();
            ++pfbegin;
        }
}

这是crtdll的一段相关代码,按注释的解释,这个函数的功能就是,从pfbegin 开始 一点一点往 pfend移动,并且调用(**pfbegin)()。这里调用的函数就是类的构造函数。在这些构造函数里面,根据需求,分配内存。
那么问题就清晰了,我的DLL里面有一些全局的变量(类),这些变量在DLL加载的时候,初始化,构造,分配了内存。但是很多的时候,DLL有全局变量,并没有内存泄露的LOG。是因为你的全局变量里面有STL容器这个的数据,容器初始化的时候,会在堆上分配内存,如果只是一般变量,那它是放在全局数据区的。
CRT报内存泄露,是因为,当程序退出的时候,CRT卸载的时候,你的全局变量的析构还没有调用,所以它就把堆上那些还没有释放的资源打出来。然后我找了一圈,可不可以让crt最后卸载呢,没找到方法,后来就把这些全局的变量的初始化和回收封装成方法,在DLL使用前和程序退出的时候分别调用。
总结就是,规范编写DLL,不然到后期优化的时候很蛋疼。

内存加载动态库 MemoryLoadLibrary 有例子。 /* * Memory DLL loading code * Version 0.0.3 * * Copyright (c) 2004-2013 by Joachim Bauch / mail@joachim-bauch.de * http://www.joachim-bauch.de * * The contents of this file are subject to the Mozilla Public License Version * 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is MemoryModule.h * * The Initial Developer of the Original Code is Joachim Bauch. * * Portions created by Joachim Bauch are Copyright (C) 2004-2013 * Joachim Bauch. All Rights Reserved. * */ #ifndef __MEMORY_MODULE_HEADER #define __MEMORY_MODULE_HEADER #include typedef void *HMEMORYMODULE; typedef void *HMEMORYRSRC; typedef void *HCUSTOMMODULE; #ifdef __cplusplus extern "C" { #endif typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *); typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *); typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *); /** * Load DLL from memory location. * * All dependencies are resolved using default LoadLibrary/GetProcAddress * calls through the Windows API. */ HMEMORYMODULE MemoryLoadLibrary(const void *); /** * Load DLL from memory location using custom dependency resolvers. * * Dependencies will be resolved using passed callback methods. */ HMEMORYMODULE MemoryLoadLibraryEx(const void *, CustomLoadLibraryFunc, CustomGetProcAddressFunc, CustomFreeLibraryFunc, void *); /** * Get address of exported method. */ FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR); /** * Free previously loaded DLL. */ void MemoryFreeLibrary(HMEMORYMODULE); /** * Find the location of
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值