【问题标题】:Using of overloaded new/delete and STL in shared library在共享库中使用重载的 new/delete 和 STL
【发布时间】:2020-08-05 17:26:03
【问题描述】:

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

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

当我使用 -O1 及更高版本编译库时,我得到 SIGABRT,这是由于在 basic_string 构造函数/析构函数中使用了不同的运算符 new/delete 造成的。 new 是从 libstdc++.so 调用的,但 delete 是从我的库调用的。

当我使用 -O0 或 -fno-inline 运算符编译库时,new/delete 用于 basic_string 构造函数/析构函数都从 libstdc++ 调用。

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

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

我使用 glibc 2.27、gcc 5.5.0

很高兴听到任何想法:)

谢谢!

【问题讨论】:

  • newdelete 有不同的重载。无法真正知道std::string 的实现在幕后做了什么。如果我是你,我真的不会采用这种方法,而是我会实现一个自定义分配器并在容器上使用它。
  • 即使this refers to Windows DLL's,这也可以解释您遇到的问题。

标签: c++ gcc stl operator-overloading std


【解决方案1】:

您的基本问题是您试图拥有多个不同的全局 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 来分配/释放内存。

【讨论】:

  • 解决我的问题的最好办法是不要重载全局new/delete。不幸的是,我没有这样的选择。 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 2017-12-07
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多