【问题标题】:operator new already defined in custom memory manager with libraryoperator new 已经在自定义内存管理器中定义,带有库
【发布时间】:2011-12-02 09:04:55
【问题描述】:

抱歉标题不好,但希望描述更清楚。

目前,我有一个与其他库(如 libpng、libvorbis 等)一起构建的主要应用程序。我正在尝试将 libtheoraplayer 添加到主应用程序,但我一直遇到问题:

1) 链接到预先构建的 llibtheoraplayer 库并包含适当的头文件时,我会收到一个错误,提示找不到 pushMemoryManager(我们自定义内存管理器的一部分)

2) 与主应用程序一起构建库导致链接器错误“error LNK2005: "void * __cdecl operator new(unsigned int,void *)" (??2@YAPAXIPAX@Z) 已在 win32Mem 中定义。对象”

我不太确定从哪里开始调试它。主应用程序不支持 STL,我首先将 libtheoraplayer 中对 STL 的引用更改为我们自己的 STL 替换,但在找到有问题的文件并更改它们后,我仍然遇到上述错误 2。

有什么疯狂的想法吗?

【问题讨论】:

  • 替换标准库(如果只是 STL 部分)是愚蠢的,除非你有一个很好的理由。
  • 有一个该死的好理由来替换 STL。旧版本的 Microsoft STL 耗费了大量时间,而其 STL 的某些组件仍然如此。然而,更换它们的分配器几乎是不可能的。

标签: c++ memory stl


【解决方案1】:

使用/FORCE 消除链接器错误(转换为警告),并祈祷没有最终使用不同分配器的跨库分配。

在 Windows(NT 或 CE)上替换分配函数相当困难,因为:

  1. 动态符号是从特定库加载的,因此您将替换代码中使用的分配器,而不是动态链接的库中使用的分配器。如果您不动态链接并使用/FORCE 消除链接器错误,它将做正确的事情并覆盖标准库中的分配器就好了。

    如果使用动态链接,如果一个库中的代码分配而另一个库中的代码释放,则使用的分配器会不匹配,因此可能会崩溃。不幸的是,即使两个函数都由同一个库定义,它也可能很容易发生,但其中一个是模板(因此实例存在于引用它的库中)而另一个不是(因此它存在于定义它的库中) .

  2. 它们有一些非标准的分配器入口点,有时在其他代码中使用它们。我们曾经使用duma 库并且实际上设法覆盖了 C (malloc/realloc/free) 和 C++ (operator new 和 operator delete) 分配器,但是当我们开始使用 iostreams 时碰壁了,它们使用标准函数进行分配,但可以通过__debug_free 或其他方式免费使用。

在旁注中,这在 Linux 上绝对是微不足道的,因为在 GNU libc malloc 中,realloc 和 free 通过您可以轻松覆盖的指针调用真正的分配器(operator new 和 operator delete 基本上分别只调用 malloc 和 free无处不在)。

【讨论】:

  • 感谢您的洞察,但我们决定手动梳理源代码并用我们自己的替换替换 std::list、std::map 和 std::vector :(
猜你喜欢
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 2011-06-01
  • 1970-01-01
  • 2017-07-26
  • 2020-03-21
相关资源
最近更新 更多