动态链接库内存分配(转)

来源:互联网 发布:oracle数据库索引失效 编辑:程序博客网 时间:2024/06/04 00:57

本文主要是探讨关于在动态链接库分配的内存在主程序中释放所产生的问题,该问题是我在刚做的PJP工程中所遇到的,由于刚碰到之时感动比较诡异(这也是学识不够所致),所以将它写下来,大家一起分享.

       问题来由:
由于该工程中要用到声音,所以我的分工之一就是用DirectMusic和DirectSound来开发声音播放的动态库,以提供给该工程的两个部分:仿真控制部分( 语音 )和三维部分( 场景声音 )使用,两个工程中的声音都以单独的线程播放,且两个线程几乎相同.,然而该动态库在以前的运行中一直没有出现过问题, 直到工程开发即将要结束阶段的前一个星期,我碰才到了这个问题,首先是三维部分中声音在第一次播放是没有问题,在播放第二个声音就出了问题(老是这样),但是仿真控制部分还是没有出现问题,我查不出错误,就用前一天的三维的版本来运行,重新生成后声音播放没有问题,初步以为是我同事当天写的代码有问题,可是第二天,同样的问题又发生了,还是那样,三维有问题,仿真部分没问题,怎么回事呢?我将三维的声音线程写成和仿真部分一样的,还是三维出问题,仿真没问题.我不相信是动态库中出问题,同一个动态库,同样的代码,只是在两个不同的程序里,为什么一个出问题,而另一个不出问题呢?
       出错信息如下:
                  windows已在PowipD.exe中触发一个断点.
                  其原因可能是堆被损坏,这也说明PowipD.exe中或它所加载的任何DLL中有bug.
                  输出窗口可能提供了更多诊断信息
       按下中断后输入窗口出现的信息如下:
               HEAP[PowipD.exe]:Invalid Address specified to RtlValidateHeap( 01CC0000, 03723758 )
               Windows已在PowipD.exe中触发一个断点.
               输出窗口可能提供了更多诊断信息
       由于这些原因让我迷惑不解,到底是为什么出现这种奇怪的事情呢?问题出在那里?
 
问题的解决:
简单地说:DLL中分配的内存DLL要负责释放!(一个模块分配的内存要在同一个模块中释放!)
找到解决方法后我查看了三个工程的设置(三个工程皆用VS2005开发):
       三维:使用MDd(多线程调试DLL)运行期库
       仿真控制:使用MTd(多线程调试)运行期库
       声音动态库:使用MDd(多线程调试DLL)运行期库
于是,我将三个工程皆改为:使用MDd(多线程调试DLL)运行期库时,问题解决。
但是如果三个工程中有的不是用C/C++写的,或者其中有工程的设置已经不便更改了,那又有什么办法呢?
该问题主要是关于DLL与进程的地址空间的问题(下面是<<核心编程>>中的一段话):
单个地址空间是由一个可执行模块和若干个DLL模块组成,这些模块中,有些可以链接到静态版本的C/C++运行期库, 有些可以链接到一个DLL版本的运行期库,而有些模块(如果不是用C/C++编写的话)则根本不需要C/C++运行期库,许多开发人员经常会犯一个常见的错误,因为他们忘记了若干个C/C++运行期库可以存在于单个地址空间中.请看下面的代码(下面代码不是书上的):
DLL中如下:
       int *DllFunc()
{
       int *p = new int;
       return p;
}
 
EXE中如下:
void EXEFunc()
{
       int *p = DllFunc();
       if( p!= NULL )
              delete p;
}
 
如何看待这个问题呢?上面的代码能够正确运行吗?DLL函数分配的内存是由EXE的函数释放的吗?答案是可能的.上面显示的代码并没有提供足够的信息.如果EXE和DLL都链接到DLL的C/C++运行期库,那么上面的代码将能够很好地运行.但是,如果两个模块中的一个或者两个链接到静态C/C++运行期库,那个对delete的操作就会失败.
一个很方便的方法可以解决这个问题.当一个模块提供一个用于分配内存块的函数时,该模块也必须提供相应的释放内存的函数,将上面的代码改成如下的样子就不会出错了:
 
DLL中如下:
       int *DllFunc()
{
       int *p = new int;
       return p;
}
 
void DLLDelete( int *p)
{
       if( p != NULL )
              delete p;
}
 
EXE中如下:
void EXEFunc()
{
       int *p = DllFunc();
       DLLDelete( p );
}
这样的代码才是正确的,当我将代码改成如上类似后,再将三维的运行期库改为原来一样(使用MDd(多线程调试DLL)运行期库),三维的声音也正确无误地播放出来了。当你在编写一个模块时,你时刻都得记着,别人的代码不一定是用C/C++写的,也有可能不能同时链接到DLL的C/C++运行期库。malloc和free函数也有类似的问题。
当然在你在生成你的模块时是可以选择运行期库的,VC 6.0配有6个运行期库:其描述如下:
库名
描述
LibC.lib
用于单线程应用程序的静态应用程序的静态链接库      
LibCD.lib
用于单线程应用程序的静态链接库的调试版
LibCMt.lib
用于多线程应用程序的静态链接库的发行版
LibCMtD.lib
用于多线程应用程序的静态链接库的调试版
MSVCRt.lib
用于动态链接MSVCRt.dll库的发行版的输入库
MSVCRtD.lib
用于动态链接MSVCRtD.dll的调试版的输入库。该库同时支持单线程应用程序和多线程应用程序
库名
描述
LibC.lib
用于单线程应用程序的静态应用程序的静态链接库      
LibCD.lib
用于单线程应用程序的静态链接库的调试版
LibCMt.lib
用于多线程应用程序的静态链接库的发行版
LibCMtD.lib
用于多线程应用程序的静态链接库的调试版
MSVCRt.lib
用于动态链接MSVCRt.dll库的发行版的输入库
MSVCRtD.lib
用于动态链接MSVCRtD.dll的调试版的输入库。该库同时支持单线程应用程序和多线程应用程序
库名
描述
LibC.lib
用于单线程应用程序的静态应用程序的静态链接库      
LibCD.lib
用于单线程应用程序的静态链接库的调试版
LibCMt.lib
用于多线程应用程序的静态链接库的发行版
LibCMtD.lib
用于多线程应用程序的静态链接库的调试版
MSVCRt.lib
用于动态链接MSVCRt.dll库的发行版的输入库
MSVCRtD.lib
用于动态链接MSVCRtD.dll的调试版的输入库。该库同时支持单线程应用程序和多线程应用程序

 

库名
描述
LibC.lib
用于单线程应用程序的静态应用程序的静态链接库      
LibCD.lib
用于单线程应用程序的静态链接库的调试版
LibCMt.lib
用于多线程应用程序的静态链接库的发行版
LibCMtD.lib
用于多线程应用程序的静态链接库的调试版
MSVCRt.lib
用于动态链接MSVCRt.dll库的发行版的输入库
MSVCRtD.lib
用于动态链接MSVCRtD.dll的调试版的输入库。该库同时支持单线程应用程序和多线程应用程序

 

而VS2005中只配了4个C/C++运行期库,就是上表中的后面4个。
建议各位在软件开发时同一软件的不同模块最好使用一致的运行库,否则还可能出现链接问题。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 wow牧师选错了圣物怎么办 淘宝有几个订单被管控了怎么办 埋线双眼皮一个宽一个窄怎么办 把维D和维C一起吃了怎么办 微信出现当前登录环境异常该怎么办 去麦加朝觐人要出现死亡怎么办 炉石传说偶数骑削弱后怎么办 出于安全和性能方面的原因怎么办 怀孕后不知道拍过好几次牙片怎么办 百度云种子含有非法离线内容怎么办 苹果手机上的迅雷怎么打不开怎么办 微信绑定银行卡收不到验证码怎么办 支付宝转账为什么没验证码怎么办 电视时间比手机慢三分钟怎么办 13岁现在有月经又流鼻血怎么办 酒店给客人把房间开错了怎么办 手机百度云下载的视频分解了怎么办 知道家人被绑架北派传销怎么办 接手前同事的客人无回复怎么办 喝了酒第二天一直吐怎么办 孩子看的鬼片不敢睡觉害怕怎么办 宝宝满月了脸还有点黄怎么办 我情人天天说没时间出去该怎么办 两个月宝宝下体三角区肿了怎么办 夏养的龙猫家里有味怎么办 不小心踩到仓鼠吐血了怎么办 不小心踩到仓鼠的头怎么办 母仓鼠生完孩子特别暴躁怎么办 被仓鼠咬出血怎么办要不要打针 被小仓鼠咬出血了该怎么办 仓鼠咬破手指流血了该怎么办 小仓鼠的手被棉花丝绑住了怎么办 荷兰猪如果不小心撞流血了怎么办 帮同事刷杯子但把杯子弄坏了怎么办 贵宾犬喜欢张开嘴巴跟人玩怎么办 鼻烟放了几天感觉跟受潮一样怎么办 两个月宝宝鼻屎堵住鼻子怎么办 肉包着智齿怎么办洗燥电影完整版 大腿内侧突然长黑痣越来越大怎么办 肚脐发炎、不脱落怎么办_妈网百科 老公出轨找个按摩的还不离婚怎么办