C++开发DLL中使用new和delete注意事项

来源:互联网 发布:centos vim安装包下载 编辑:程序博客网 时间:2024/05/16 02:58

报错情况

1,在 DLL 中用 new 来创建宿主程序中的对象,然后把这个对象指针保存到宿主程序,当 DLL 被卸载后,凡是涉及到这个指针的调用都会报错,包括 delete 这个指针也会有错。

2,在DLL中new出一个对象,然后在不需要使用时进行delete,结果会报如下错误:

Windows has triggered a breakpoint in wsTest.exe.
This may be due to a corruption of the heap, which indicates a bug in wsTest.exe or any of the DLLs it has loaded.




分析原因

因为new/delete使用的是局部堆(当然这与编译器可能也有关,但至少M$的编译器应该是这样的),也就是说不同的DLL虽然共享一个地址空间,但完全可能会维护不同的局部堆(堆分段),这与编译器的实现有关。有些编译器可以选择使用进程共享的局部堆,但性能会受影响。

如果是不同的局部堆,当你在DLL中new时,是在DLL的堆中分配的;而当你在EXE中delete时,EXE会认为它是在EXE的局部堆中分配的,从而用EXE的堆信息去释放它,从而可能导致错误。具体情况与堆管理代码的实现有关。

解决办法
1、为class或struct提供一个虚的create/free方法,在里面调用new/delete。不管是从EXE中分配的还是从DLL中分配的,都可以安全地用create方法创建/free方法释放,因为create/free是虚的,它的代码会和分配它的代码编译在同一个可执行体中。

2、用globalalloc()和globalfree()代替new和delete。

3、用动态库版本的c run-time library可以解决这个问题。
在project->setting->c/c++->category中选code generation,然后在use run-time library中选debug multithreaded。

4、重载new/delete操作符。

0 0
原创粉丝点击