Linux C/C++动态库中的内存分配/释放

4
我需要将我的应用程序分成几个逻辑模块。
“mainapp”:
- “module1.so” - “module2.so” - “module3.so” - 以此类推
每个模块都是一个“*.so”库,在运行时将被加载。
每个模块共享相同的接口并返回一些数据数组。例如:
int *ptr = module1->getIntData();
在“mainapp”方面释放/删除这个内存是否可以?
int *ptr = module1->getIntData();
delete ptr; //(or free(ptr))

关于malloc/free实现问题。库是否可能使用与主应用程序不同的实现?


1
你可能没问题,但是如果你提供了一个 createThing() 方法,为了一致性,最好也提供一个 destroyThing() 方法,即使没有其他原因。 - trojanfoe
你是否正在遵循任何同步机制?例如:mutex或其他什么。 - someone
1
实际上,这更多是一种约定而非技术问题。也就是说,在技术上它是可以的,但重要的是明确同意哪一方拥有库方法分配的数据。 - user3159253
2
我建议返回类似于std::unique_ptr这样的东西,而不是原始指针,因为unique_ptr/shared_ptr允许在对象创建时指定删除器,从而简化内存管理并使显式删除函数过度。 - user3159253
选择 unique_ptrshared_ptrweak_ptr 取决于所有权策略。 - user3159253
1个回答

5
我强烈建议负责分配的模块也应该负责回收。因此:
int *ptr = module1->getIntData();
...
module1->freeIntData(ptr);

这使得不同的模块可以使用不同的分配器(malloc / free,new / delete,slab分配器等),而不会有困难。

在Posix系统上,一个进程中只能有一个malloc(和free)的实现,因此如果getIntData的定义是“返回必须由free释放的指针”,那么你就没问题了。另一方面,我认为可能会编写两个用于编写module1和module2的C ++编译器,但是它们可能无法使用另一个的new分配的内存。(尽管我认为目前不存在这样的编译器)

如果有丝毫可能性需要将其移植到Windows,则确实希望模块释放其分配的内存。不同的DLL可以有不同的堆栈,并可能出现各种有趣的问题。(正如@trojanfoe在评论中所说:仅在调试和发布版本之间的区别就足以引起烦恼。)

我只建议在您可以保证所有模块始终使用相同版本的相同编译器并使用相同的编译器标志的情况下才使用std::unique_ptr。我坚信将动态库接口尽可能简单和类似于C。


如果我没记错的话,你只需要将Windows DLL以调试模式构建,然后将可执行文件以发布模式构建,就可以展示你在回答中解决的问题。 - trojanfoe
std::unique_ptr很好,因为我可以将自定义(库)分配器传递给它。 - Dejwi
@trojanfoe:哈!不错的弗洛伊德失误 :-) - Martin Bonner supports Monica
@Dejwi:我不会相信编译器/库会使std::unique_ptr在调试和发布版本中具有相同的ABI。 - Martin Bonner supports Monica

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