关于用DLL接中使用std::vector之后出现的问题

最近在代码中用了这样一个DLL,采用静态加载方式使用,原型类似如下:

XXX_API  int xx_func(std::vector<struct xx> &xx_tbl, ..., ...);
//代码中会用xx_tbl.push_back(xx);之类的代码向xx_tbl里面填充数据

但是却出现一个奇葩问题,每当调用这个DLL的程序退出时Debug版本有很大概率会崩溃在这个std::vector<struct xx>的析构函数上。

研究了好久才发现,当DLL中调用push_back函数时,其实std::vector<struct xx>的构造函数分配的内存是属于这个DLL的资源,当程序退出时会首先卸载这个DLL程序,那么与他相关的内存也随之被释放。

当主程序最后退出时,就会引发xx_tbl的析构函数,但是由于xx_tbl中的某些元素的内存是在DLL中分配的,而且已经被释放了,那么这些内存在被析构函数释放时就会引出错误,Debug版的代码是有内存检查的,因此每次Debug代码退出时就会崩溃。

因此,对于DLL中尽量采用纯C的结构,不要使用对象。

————————————————————————————————–
后来找到原因,因为动态链接库使用的CRT库是静态链接的,与Exe程序使用的是两个不同的CRT,因此在DLL中向vector中push数据之后会,会调用DLL链接的CRT进行分配内存,如果在Exe中使用了被DLL操作过的vector变量时,就会导致vector变量进行resize,而由于Exe与DLL使用的是两个CRT库,这时就会造成信息错乱,引起程序崩溃,只要将所有DLL设成使用动态加载CRT即可解决此问题。



发表评论