为什么指针不能跨程序集被删除?

3
最近我在这里发现,指针(或至少是数组)不能在其内存创建的不同程序集中删除。据我所知,指针是内存中具有另一个变量地址值的变量。因此,为什么指针的值(即变量的地址)无法被擦除,并且其内存可以从另一个程序集中释放?

你所说的汇编是指什么?也许这与翻译单元相同吗? - Vaughn Cato
3
您在这里使用了“assembly”,但我认为您可能指的是库或DLL。无论如何,newdelete的底层实现可能因所使用的DLL /库而异,这会在混合匹配时导致损坏。 - Joe
原谅我的无知,我是从.NET转到C ++的,并将汇编和库视为同义词(实际上我不太清楚区别)。@Joe,不同的newdelete实现是否都一样?你能举个例子说明有问题吗? - JMCF125
4
阅读此文:跨模块边界分配和释放内存 - DCoder
你分享的链接很棒,@DCoder。我已经阅读并标记以备将来参考。 - JMCF125
1个回答

3
任何动态分配的内存都需要返回到它所属的堆中。每个 DLL(我认为一个 assembly 对应一个 DLL)都可以拥有自己的堆,因此你需要在分配内存的同一 DLL 中释放内存,否则会发生奇怪的事情(未定义的行为 - 例如错误或崩溃)。因此,除非你知道两个不同的模块(DLL、程序集)具有相同的堆,否则无法在一个模块中释放另一个模块中分配的内存。
将内存块返回到其来自的堆类似于将图书还错给了“错误”的图书馆- 当图书管理员在原始图书馆找不到这本书时,就会引起混乱,而“新”图书馆也不知道这本书。想象一下,如果我们在去图书馆时都这样做... 堆将包含跟踪堆中对象的内部数据结构。如果我们突然开始将它们放回它们不属于的地方,就会发生奇怪的事情。

1
请注意:"每个DLL都有自己的堆"这一说法并不是必然的。您可以编译DLL以使用共享堆,也可以编译它们以使用独立堆。 - Yakk - Adam Nevraumont
感谢您的回复,已经进行了澄清。 - Mats Petersson
@MatsPetersson,感谢您的回答。我认为图书馆的比喻也使得问题更加清晰有趣。 - JMCF125
1
@JoãoMiguel:在其他操作系统中也可能出现这个问题。任何不是从单个堆中分配内存的操作系统都会有这个问题(除非操作系统有某种特殊机制来跟踪“这是在哪里分配的”)。当然,C和C++都允许程序员制作自己的内存分配版本 - 当然,如果在Linux中从mmap分配了一些内存,则不能只是将其传递给freedelete以释放它。 - Mats Petersson
1
@JoãoMiguel,在Linux中,所有的分配都通过相同的底层机制进行,到达同一个堆。即使是使用不同版本编译器编译的部分也是如此。当我看到这个问题时,我真的觉得这非常奇怪... - vonbrand
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接