核心编程第465页没看懂

flamingheart 2007-08-06 08:56:13
注意必须注意的是,单个地址空间是由一个可执行模块和若干个D L L模块组成的。
这些模块中,有些可以链接到静态版本的C / C + +运行期库,有些可以链接到一个D L L版本的C / C + +运行期库,而有些模块(如果不是用C / C + +编写的话)则根本不需要C / C + +运行期库。许多开发人员经常会犯一个常见的错误,因为他们忘记了若干个C / C + +运行期库可以存在于单个地址空间中。请看下面的代码:

【代码】

那么你是怎么看待这个问题的呢?上面这个代码能够正确运行吗? D L L函数分配
的内存块是由E X E的函数释放的吗?答案是可能的。上面显示的代码并没有为你提供
足够的信息。如果E X E和D L L都链接到D L L的C / C + +运行期库,那么上面的代码将能够很好地运行。但是,如果两个模块中的一个或者两个都链接到静态C / C + +运行期库,那么对free函数的调用就会失败。我经常看到编程人员编写这样的代码,结果都失败了。

为什么“如果两个模块中的一个或者两个都链接到静态C / C + +运行期库,那么对free函数的调用就会失败”?
...全文
167 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jasonshark 2007-08-06
  • 打赏
  • 举报
回复
对,是把CRT代码都链到自己的目标文件了
但是那个堆的句柄是个全局变量(大概是,记不太清了),如果静态链接的话就需要在Module中保留这样一个全局的堆句柄, 其实也就是把这个堆独立出来了.

你可以对照一下动态链接到CRT的情况: 大家调用进程空间中唯一的一个msvcrt.dll中的malloc或free, 而这个msvcrt.dll肯定只有一个堆, 因此结果就是大家都在同一个Heap上进行分配和释放
flamingheart 2007-08-06
  • 打赏
  • 举报
回复
楼主怎么光问问题,又不发表自己的感想啊?而且还不结帖...
http://community.csdn.net/Expert/TopicView3.asp?id=5692838
http://community.csdn.net/Expert/TopicView3.asp?id=5684762
------------------------
不好意思,这两个帖子也是前两天问的,现在已经结贴了。
flamingheart 2007-08-06
  • 打赏
  • 举报
回复
有些明白了,还有一点比较糊涂的是静态连接在编译的时候不是把库中的代码都拷贝到自己的代码中了吗,不就和自己写的代码一样了吗?为什么还用静态Module自己的堆呢?
jasonshark 2007-08-06
  • 打赏
  • 举报
回复
楼主怎么光问问题,又不发表自己的感想啊?而且还不结帖...
http://community.csdn.net/Expert/TopicView3.asp?id=5692838
http://community.csdn.net/Expert/TopicView3.asp?id=5684762

再回答一次..
因为CRT是有自己的堆来分配空间的。在一个进程空间中, 静态链到CRT上的Module(下简称静态Module)都有一个独立的CRT堆, 而动态链到CRT上的Module(下简称动态Module)则共同使用msvcrt.dll所创建的堆,这样如果一个变量的空间如果是在静态Module中分配而在动态Module中释放的话, 调用free肯定是不行的(因为HeapAlloc跟HeapFree的Heap都不同)。如果是在Dubug Build下会有Debug Assert.

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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