首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨共享库边界分配和释放内存

跨共享库边界分配和释放内存
EN

Stack Overflow用户
提问于 2020-10-28 22:13:39
回答 2查看 352关注 0票数 6

在使用windows dll时,我们应该将内存分配/释放限制在dll边界内,因为dll可以使用自己的堆。所以我们有从dll导出分配器和自由函数。

代码语言:javascript
复制
IsomeInterface* getObject();
void freeObject(IsomeInterface *object);

这样,对象的创建和删除将驻留在dll中。

linux上的共享库也存在这个问题吗?在处理共享库(.so)时,我们还需要注意在共享库中保持分配/释放。我在下面做了一些快速试用,它在linux上工作。同样的例子不适用于windows dll (如果用/MD编译的exe和dll都使用相同的堆,它将适用于windows dll )。

代码语言:javascript
复制
std::vector<int> vec;
vec.push_back(42);
PassAVector(vec);

PassAVector驻留在共享库中的位置

代码语言:javascript
复制
void PassAVector(std::vector<int> &vec)
{
     vec.push_back(1);  // These would cause reallocation
     vec.push_back(2);
     vec.push_back(3);
     vec.push_back(4);
     vec.push_back(5);
}

这是否意味着unix上的共享库与可执行文件共享堆(相当于windows上的/MD开关)?

有没有可能编译(一些编译器标志)共享库(.so)或linux上的可执行文件,使它们开始使用不同的堆(windows上的/MT开关),并且这个问题浮出水面?

编辑:找到了this,它似乎建议跨边界传递STL,只要编译器是gcc就可以了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-01 00:37:15

只要你坚持使用Glibc或者其他“普通”的分配器(jemalloc,tcmalloc等)堆状态将由所有库共享,因此您将能够使用malloc在您想要的任何地方释放分配的内存。

从理论上讲,有可能绕过这一点。例如,一些库可能链接到malloc/free的自定义实现(通过-Bsymbolic的符号脚本技巧),它有自己的私有堆,因此不能与程序的其他部分很好地交互。但我在现实生活中从未见过这样的事情。

STL容器基于malloc/free,因此也可以跨库边界传递/修改它们。当然,不同的库可以使用不同的编译器和不同的STL不兼容版本(例如libstdc++、libcxx等)进行编译。但是它们的C++容器类型是不同的,并且编译器不允许您在不兼容的模块之间传递它们。

票数 4
EN

Stack Overflow用户

发布于 2020-11-03 16:04:42

在C++中,更改堆的常规方法是重载全局操作符new/delete。

在Windows中,这种重载仅限于特定的dll,因此您会遇到问题。

在Linux中,重载的全局运算符通常是真正的全局运算符-因此第一个全局运算符获胜,但如果您确实希望在其中包含特定的堆,则可以实现这一点(然后您需要导出分配和释放函数):

C++ custom global new/delete overriding system libraries

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64574662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档