dll中new 一个类, dll外delete

MK菠萝 2013-04-25 10:32:10
int main()
{
Class1* pClass= CreateObj();
delete pClass;
}

CreateObj()函数是dll中的函数,用于new一个Class1的派生类,并返回基类Class1的指针。
为什么在dll外释放没有问题?
...全文
571 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
iceheart 2013-04-27
  • 打赏
  • 举报
回复
1、内存的分配和释放,一定会读写某些全局变量(运行时库里的)。 2、编译链接成二进制模块,这些全局变量会成为二进制模块的一部分。 3、进程里有多个二进制模块,这些全局变量就很可能会有多份。从A那里new的去B那里delete,没人敢担保程序正常运行。 所以,谁分配的内存谁释放,是基本原则,不能改。
MK菠萝 2013-04-27
  • 打赏
  • 举报
回复 1
问题已经解决了, 我总结一下: 1) dll用MTd , exe用MTd (即dll 和 exe 维护不同堆) 当在dll中new 一个类,且类的析构函数非虚时,dll导出类指针, 在dll外delete这个类指针, 此时会出错,大家都懂得原因。 当在dll中new 一个类,且类的析构函数为虚时,dll导出类指针, 在dll外delete这个类指针, 此时不出错,因为此时调用的是dll的delete,虽然是在exe中用的。 2) dll用MDd ,exe用MDd (即dll 和 exe 用同一个堆) 不会出任何问题,大家也知道原因。 当然最好还是遵守在哪创建,在哪释放原则。 感谢各位回答, 受益良多!
  • 打赏
  • 举报
回复
引用 5 楼 mujiok2003 的回复:
[quote=引用 2 楼 starytx 的回复:] 不管在哪里只要delete的指针保存的地址和那个new返回的一样就可以
未必,比如虚函数实现。 [/quote] 什么意思?
赵4老师 2013-04-26
  • 打赏
  • 举报
回复
参考《深入解析Windows操作系统-Windows Internals》中进程管理和内存管理相关章节。
Red_angelX 2013-04-26
  • 打赏
  • 举报
回复
如果是多个dll则不行 因为windows下一个dll有一个堆 linux下没问题 共用一个堆
lm_whales 2013-04-26
  • 打赏
  • 举报
回复
内存管理体系,才是核心 如果运行时库是相同的; 重要的是,管理内存的代码必须是同一段代码,才不会出问题。 至于是否同一堆的问题,未必同一内存管理系统,只维护一个堆,也可能同时维护一批堆; 当然只维护一个堆最简单最方便。 即使同一个堆,不同内存管理系统,一起管理也会出乱子。
lm_whales 2013-04-26
  • 打赏
  • 举报
回复
不同开发工具,生成的动态库,内存布局不同或者说,内存管理函数不同,new ,和delete不配对,会出问题的。 同一开发工具的同一版本,同一编译配置,针对同一平台(CPU,32或者64位,操作系统)的代码。如果new delete 调用的代码是共享的(DLL和exe 共享的)应该没有问题的。 否则会有两个内存管理体系存在,会出现冲突的。
Ahh_Freshmeat 2013-04-26
  • 打赏
  • 举报
回复
是不是可以DLL导出类 这样不就方便了么
赵4老师 2013-04-26
  • 打赏
  • 举报
回复
引用 34 楼 fthislife 的回复:
[quote=引用 26 楼 Lonely_Snow 的回复:] http://msdn.microsoft.com/en-us/library/ms235460 http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
++[/quote] 帖主的代码用CRT了吗? 但是我还是从这两个链接中学到了相关知识,感谢26楼。
sduxiaoxiang 2013-04-26
  • 打赏
  • 举报
回复
无所谓 内存操作好就可以了 不过不推荐这么玩
derekrose 2013-04-25
  • 打赏
  • 举报
回复
引用 11 楼 dahaiI0 的回复:
引用 10 楼 derekrose 的回复:如果对于堆来说,每个DLL有自己的堆,那么从DLL中动态分分配的内存最好是从DLL中删除。如果从DLL中分配内存,然后再EXE中或者另外一个DLL中删除,很可能导致程序崩溃。 每个DLL都有自己的堆?貌似不太对吧
嗯,的确不对,这段话是复制的。
一叶之舟 2013-04-25
  • 打赏
  • 举报
回复
如果运行库不一样,比如debug和release的区别,多线程和单线程区别,DLL中创建,DLL外删除就有问题了。
一叶之舟 2013-04-25
  • 打赏
  • 举报
回复
如果运行库是相同的,就没关系。
  • 打赏
  • 举报
回复
想出错很容易,dll或exe其中一个或全部都使用 静态链接运行库. 不要都使用链接动态运行库.
三文鱼也会飞 2013-04-25
  • 打赏
  • 举报
回复
刚才写错了 引用 7 楼 xu561865 的回复: 我知道在dll中创建,要在dll中释放,只是想知道为什么。 new的代码是写在DLL中的,但不等于new的资源在DLL中,系统加载DLL后,DLLnew的资源也是系统的堆区,delete pClass;也是系统的堆区,当然可以释放了。
三文鱼也会飞 2013-04-25
  • 打赏
  • 举报
回复
引用 7 楼 xu561865 的回复:
我知道在dll中创建,要在dll中释放,只是想知道为什么。
new的代码是写在DLL中的,但等于new的资源在DLL中,系统加载DLL后,DLLnew的资源也是系统的堆区,delete pClass;也是系统的堆区,当然可以释放了。
www_adintr_com 2013-04-25
  • 打赏
  • 举报
回复
如果使用静态链接的话, 每个 dll 确实都是有自己的堆的. 如果使用动态链接, 所有的 dll 都会调用 msvcrXX.dll(具体名字可能不对) 中的 new 函数, 使用的都是这个 dll 中的堆句柄, 是相同的.
dahaiI0 2013-04-25
  • 打赏
  • 举报
回复
引用 10 楼 derekrose 的回复:
如果对于堆来说,每个DLL有自己的堆,那么从DLL中动态分分配的内存最好是从DLL中删除。如果从DLL中分配内存,然后再EXE中或者另外一个DLL中删除,很可能导致程序崩溃。
每个DLL都有自己的堆?貌似不太对吧
derekrose 2013-04-25
  • 打赏
  • 举报
回复
如果对于堆来说,每个DLL有自己的堆,那么从DLL中动态分分配的内存最好是从DLL中删除。如果从DLL中分配内存,然后再EXE中或者另外一个DLL中删除,很可能导致程序崩溃。
加载更多回复(17)

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧