gpt4 book ai didi

c++ - 在 OSX 上替换 libstdc++.dylib (4.0) 全局新建和删除运算符

转载 作者:太空狗 更新时间:2023-10-29 23:09:50 24 4
gpt4 key购买 nike

我正在努力用 XCode 3.2、GCC 4.2、libstdc++ 4.0、动态版本替换全局的 new 和 delete 运算符。

我直接从 header “new”中获取原型(prototype)并实现它们。它们粘贴在下面。

该项目是一个 .plugin,因此是一个动态库。此插件必须将分配委托(delegate)给主应用程序自己的 alloc/free 例程,这些例程位于旧的 C SDK 中。

我自己对 new/delete 的所有调用以及 std::list 和 std::map 分配都被正确替换,但不是在 std::vector::push_back 必须增加其缓冲区时。在这种情况下,我的 operator new 不会被调用,但我的 operator delete 会被调用。我知道这一点,因为我在我的新运算符(operator)分配的任何缓冲区的前四个字节中写了一个标记,并且我在运算符(operator)删除中检查了这个标记。请参阅下面的违规代码。

extern "C++"
{
__attribute__((visibility("default"))) void* operator new(std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void* operator new[](std::size_t) throw (std::bad_alloc);
__attribute__((visibility("default"))) void operator delete(void*) throw();
__attribute__((visibility("default"))) void operator delete[](void*) throw();
__attribute__((visibility("default"))) void* operator new(std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void* operator new[](std::size_t, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete(void*, const std::nothrow_t&) throw();
__attribute__((visibility("default"))) void operator delete[](void*, const std::nothrow_t&) throw();

}

以下代码将在“yo”超出范围时引发断言,因为为 std::vector 分配的内存不是由我的 operator new 分配的。

   {
std::vector<std::string> yo;
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
}

下面的代码是可以的,因为 std::vector::reserve 调用了我的 operator new:

   {
std::vector<std::string> yo;
yo.reserve(4);
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
yo.push_back("yoyoma");
}

GBD(调试器)在需要增大缓冲区时不会让 met 进入 std::vector::push_back 实现(该方法名为 _M_insert_aux)。我所知道的是,从未从 std::vector::push_back 调用我的 operator new。

上述解决方法不能应用于我正在使用的所有第 3 方库。其中之一是 push_back 的大用户。

我尝试静态链接到 libstdc++.a,但我遇到了同样的问题。

是否有一些不使用全局 new 运算符的 std::vector< std::string > 特化?

顺便说一句,这在带有 VS9 的 Windows 上完美运行。

最佳答案

我终于通过使用 George Costanza 的技术解决了我的问题:反其道而行之。

我没有尝试让我的运算符成为新的和删除可见的,而是完全隐藏了它们。

诀窍是在每个静态库和包设置中设置这些:

  • 设置 C++ 标准库类型:静态
  • 默认隐藏的符号:选中
  • 修复并继续:未选中(非常重要,否则静默禁用以前的设置)

并进行清理所有和构建,因为在 XCode 3.2 中,仅在更改这些设置后点击构建是行不通的。

显然,我将 operator new & delete 原型(prototype)更改为:

#pragma GCC visibility push(hidden)

extern "C++"
{
void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
} // extern "C++"

#pragma GCC visibility pop

不,为什么会这样?必须同时具有静态和隐藏符号才能工作。它似乎使我的捆绑插件免受内联其分配器的 STL 特化实现的影响。

另请注意,这只发生在从大型应用程序动态加载的捆绑插件中。在从控制台应用程序调用的一个简单的 .dylib 项目中,一切都可以在任何设置下正常工作。

关于c++ - 在 OSX 上替换 libstdc++.dylib (4.0) 全局新建和删除运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com