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

报错情况

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操作符。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值