关于跨dll边界删除vc2013中的指针

时间:2015-05-20 09:49:48

标签: c++ windows dll crt

Does msvcrt uses a different heap for allocations since (vs2012/2010/2013)开始,我了解到跨越模块边界的删除obj甚至可能使用ms vc2012或更新版本的MT选项,令人惊讶。

但是,在我做了一些测试之后我很困惑(我的平台是win7中的vc2013 update4)。 我在dll中新建一个obj,并在exe中删除它。 当,dll和exe都使用MT选项编译时,它看起来真的很好。 但是,当dll和exe都使用MTd编译时,会出现一个断言错误' _pfirstblock == phead'。

有人能告诉我使用由MT / MTd选项编译的模块可以在vs2013中跨越模块边界释放内存吗?

1 个答案:

答案 0 :(得分:2)

是的,CRT从VS2012开始分配默认进程堆。 GetProcessHeap()返回的那个。这种改变的主要动机可能不是改进的模块互操作,VS2012最初是在没有XP支持的情况下发布的,因此不再需要创建私有堆并调用HeapSetInformation()来打开低碎片堆。 Vista及以上版本默认启用它。

这种情况并没有持续,一场抗议活动迫使他们重新支持XP。在没有改变代码的情况下,我从未见过有人抱怨过。让你想知道是否认为需要支持古老的操作系统确实符合实际需要。

它没有做任何事情来解决因进程中有多个CRT副本而导致的其他问题。与/ MT vs / MTd一样,您的情况是,CRT的调试版本会为分配的内存块添加额外的元数据,以检测堆损坏和错误的指针使用情况。由非调试CRT分配的块中缺少该值。因此kaboom在调试CRT中将该指针传递给free()或:: operator delete调用时,它无法找回元数据。

CRT全球国家引起的其他问题。像errno,setlocale(),strtok(),strerror(),asctime(),gmtime()等。

所以基本建议不会改变,只使用/ MT用于简单的单个模块程序(只是一个EXE,没有DLL)或具有非常精心设计的接口的DLL。