如果在库函数中分配了一块堆内存,则将指针传递给加载该库的应用程序可能会适得其反。它与什么有关?
当然,我理解加载的DLL会有自己的内存管理器,会被加载到共享内存区。这意味着在其中声明的变量将存储在某种堆栈中,而动态分配的内存位于其“堆”中。malloc在内部,它似乎存储了它已分配的内存量以及分配的位置,因此,在调用时free,如果内存管理器相同,它也知道此信息的位置并知道要释放多少内存。因此,当传递指向在 DLL 中分配的内存的指针时,free它不会知道要释放多少内存。
原则上,库函数返回的指针可以在同一台机器上运行的任何程序中使用吗?
这个问题的措辞毫无意义。这里没有“不”,也从来没有。您可以向/从 DLL 传递任何指针。对此没有禁忌症 - 这是一个根本上必要的机会,没有人让你拒绝它。
自己传递指针不会适得其反。尝试释放另一个模块区域中的指定内存可能。加载的 DLL可能有自己的内存管理器。可能不是。这取决于此 DLL 的配置。
这是唯一需要记住的细节:不要假设您有权直接销毁在 DLL 中分配的对象。很可能在 DLL 中创建的所有对象都必须传回 DLL 以被销毁。
这是可能的,但他们没有。原因可能是库及其调用模块可以使用不同的分配器,然后您在调用模块中使用您的释放器?如果这个模块也是一个库,并且上面传递了指针?
这些库有自己的资源跟踪方法,如果分配器不同,执行这些功能的全局对象也不同。哪些 - 取决于编译器及其版本\程序集。即使他们最终都调用 GlobalAlloc\GlobalFree。
对不同版本的运行时库的调用访问函数的不同实例。正如历史所表明的那样,在 Microsoft 库的情况下,这会导致对堆完整性的破坏。8号工作室帮助分配的内存区域不会通过调用10号工作室库中的函数等方式删除。DLL 在 8 中编译,程序在 10 中编译。有时甚至构建编号也很重要。
提供一种用于创建和销毁对象的机制,或者最好由调用者分配内存是一种很好的做法。后者消除了 DLL 的内存管理器与程序发生冲突的任何可能性。.