在DLL中使用Vector造成程序奔溃

1、  问题描述

XP环境VS2008平台下自己写了一个DLL,然后在另外一个工程里调用了这个DLL,程序的Debug版本在XP下和Win7(装有VS2008)下可以运行,Release版本在XP下可以运行,但是在Win7下运行程序奔溃。
问题事件名称:                         APPCRASH
应用程序名:                             test.exe
应用程序版本:                         1.0.0.1
应用程序时间戳:                      53853a0f
故障模块名称:                         ntdll.dll
故障模块版本:                         6.1.7601.17725
故障模块时间戳:                      4ec49b8f
异常代码:                                c0000005
异常偏移:                                000332a0

2、问题发现

刚开始以为是程序发布平台设置的问题,因为使用的Win7是64位的,所以拼命的在网上搜索如何让32位程序在64位的系统下运行,方向不对,没有收获,突发奇想,是不是这台电脑系统有问题,然后用另外一台32位的Win7测试程序,结果程序还是奔溃了,这说明程序在win7环境下运行都失败,经过在Win7下调试,发现每次调用完DLL里面的一个函数就会出现内存释放出错,vector<CString> FunctionTest(param1,param2)然后我将函数里的内容全部注释重新编译DLL和程序发现还是有内存释放出错,最终发现问题所在:内存释放一定要遵从哪里开辟哪里释放的原则,比如说在DLL中开辟的内存就需要在DLL中释放,否则出错。

3、原因分析

因为在DLL函数中使用了Vector中pushback函数(次数比较多),使得vector内存重新分配,然后函数调用完后,vector值被传递到主程序exe里,操作结束后vector释放操作在exe中进行,所以导致程序奔溃。

4、  网上解决方案

a、  如果知道DLL中vector改变的大小,可以提前手动分配好大小(Resize),这样避免vector重新分配内存。
b、  传递vector指针
c、  传递const vector<TYPE>(这种方法不符合我这里,因为我要改变vector里值)
d、  在DLL中提供内存释放接口,手动调用释放内存函数释放内存,这样就保证了在DLL中开辟的内存在DLL中释放。(这个方案在其他例子中可行)
e、  在DLL类中声明一个Vector变量,返回值用该变量的引用(这个方法很棒,是前辈介绍的) 函数原型改为

vector<CString> & FunctionTest(param1,param2);

采用引用的形式在函数返回时不会产生内存分配操作,而且DLL中vector内存变化最终由DLL类来管理,不用程序员担心。

5、  延伸

如果是参数里面有vector也会造成程序奔溃,因为在参数传递过程中DLL中开辟了内存,解决的办法也可以采用传递引用参数的形式,而且如果参数在执行过程中不会被改变可以用const修饰如:

 vector<CString> & Function(vector<CString> & param1, const CString &param2);

至于为什么这样写,就自己多想想吧,还有一个问题就是为什么Release的程序在XP下运行没有提示任何问题,我能想到的是Win7内存优化比XP好,在XP中可能造成了内存泄露,希望有人指出真正的原因! /yh
本文原创,本文固定链接: http://www.qiezichaodan.com/programs_crash/