依旧的博客

技术学习

C++博客 首页 新随笔 联系 聚合 管理
  17 Posts :: 1 Stories :: 2 Comments :: 0 Trackbacks

如果在VC中创建一个控制台的EXE和一个Win32的DLL,从DLL中导出一个函数,该函数用new分配一块内存,返回其指针,然后在EXE中调用该函数,获得返回的指针,用delete释放这块内存,就会引发断言错误。

产生这个问题的原因是:EXE和DLL中分别静态链接了C运行时库,从而new和delete运算符来自C运行时库的不同版本。C运行时库在管理堆内存时,会使用一些全局变量来跟踪内存分配情况,因此程序中链接的C运行时库必须唯一,否则就会引起不一致。

解决的办法很简单:在EXE和DLL中都动态链接C运行时库,也就是在工程设置的Link面板选择"忽略所有默认的库",再加入msvcrt.lib。

对这个问题有两种错误的观点需要澄清:一种以为EXE和DLL有不同的堆,实际上DLL总是被映射到加载它的进程的地址空间,它没有自己的堆;一种以为DLL和EXE相对于不同的起始地址,动态链接的地址映射机制引起了前面的问题,实际上DLL是和OBJ一样的目标模块,每个目标模块都有自己的起始地址,但是链接成加载模块以后就会统一到一个起始地址,一个目标模块对其它模块的引用在链接前是以符号方式表示的,链接后会被修改成地址方式。静态链接和动态链接都会保证:加载模块是统一编址的。

参考资料:
1. http://topic.csdn.net/t/20020714/19/873683.html
2. MSDN July 2000/Knowledge Base/Windows Development/Win32 Software Development Kit/HOWTO: Use the C Run-Time
3. 《操作系统-内核与设计原理(第四版)》/William Stallings 著,魏迎梅等译 电子工业出版社

posted on 2007-01-28 14:02 依旧的博客 阅读(282) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理