在共享库中使用重载 new/delete 和 STL

Using of overloaded new/delete and STL in shared library

我遇到过由重载运算符 new/delete 的结合引起的问题STL(尤其是std::string)。这是我的情况...

我编译了共享库(称之为libfoo.so),其中重载了运算符new删除。为了不影响将使用该库的程序,我制作了符号 newdelete隐藏。 我的库也使用 STL,尤其是 std::string,正如我所料,它应该使用我的运算符 new/delete 因为它是模板class.

当我使用 -O1 及更高版本编译库时,我得到 SIGABRT,这是由于在 basic_string constructor/destructor 中使用不同的运算符 new/delete . new 是从 libstdc++.so 调用的,但是 delete 是从我的图书馆打电话。

当我使用 -O0 或 -fno-inline 运算符编译库时 new/delete for basic_string constructor/destructor 都是从 libstdc++ 调用的。

我做了最小的例子来展示这种行为:https://github.com/yekatkov/CustomNewDelete
重现错误的步骤在 Readme.md.

这是优化的正常行为吗?或者我应该以不同的方式使用 std::string 吗?如何强制我库中的 stl classes 使用我的 new/delete?假设我的真实库有大量的 stl classes,因此我无法为它们中的每一个重新定义分配器。 :(

我使用 glibc 2.27、gcc 5.5.0

乐于倾听任何想法:)

谢谢!

你的基本问题是你试图拥有多个不同的全局 operator news,一个在你的 dylib 中,另一个给任何使用你的 dylib 的人。

只能有一个。这就是它被称为 global 运算符的原因。

如果您有多个,则可以获得您所看到的行为。 (或者别的什么,你正在走进 UB-land)

(稍后) libstdc++ 和 libc++ 都在 dylib 中外部实例化 std::basic_string<char, std::char_traits<char>, std::allocator<char>>(又名 std::string)。这意味着当你在 string 中调用非内联方法时,你是 运行 dylib 之外的代码,它不会使用你的隐藏运算符 new/delete 到 allocate/free 内存.