Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 替换libstdc++;。OSX上的dylib(4.0)全局新建和删除运算符_C++_Xcode_Gcc_Stl_New Operator - Fatal编程技术网

C++ 替换libstdc++;。OSX上的dylib(4.0)全局新建和删除运算符

C++ 替换libstdc++;。OSX上的dylib(4.0)全局新建和删除运算符,c++,xcode,gcc,stl,new-operator,C++,Xcode,Gcc,Stl,New Operator,我正在努力用XCode 3.2、GCC 4.2、libstdc++4.0、动态版本替换全局new和delete操作符 我直接从标题“new”中获取protypes并实现它们。它们贴在下面 该项目是一个.plugin,因此是一个动态库。此插件必须将分配委托给主应用程序自己的alloc/free例程,这些例程位于旧的C SDK中 我自己对new/delete的所有调用以及std::list和std::map分配都被正确替换,但当std::vector::push_back必须增加其缓冲区时,就不会被

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

我直接从标题“new”中获取protypes并实现它们。它们贴在下面

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

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

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分配的内存不是由我的new运算符分配的

   {
        std::vector<std::string> yo;
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
        yo.push_back("yoyoma");
    }
{
std::向量yo;
向后推(“yoyoma”);
向后推(“yoyoma”);
向后推(“yoyoma”);
向后推(“yoyoma”);
}
以下代码正常,因为std::vector::reserve调用my操作符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");
    }
{
std::向量yo;
yo.储备(4);
向后推(“yoyoma”);
向后推(“yoyoma”);
向后推(“yoyoma”);
向后推(“yoyoma”);
}
GBD(debugger)不会让met在需要增加缓冲区时介入std::vector::push_back实现(该方法名为_M_insert_aux)。我只知道我的操作符new从未从std::vector::push_back调用过

上述解决方法无法应用于我正在使用的所有第三方LIB。其中一个是push_back的大用户

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

对于不使用全局新运算符的std::vector是否有一些专门化


顺便说一句,这在使用VS9的windows上非常有效

我不确定如何准确地执行您的请求,但您可以通过使用自定义分配器在STL中实现自己的分配语义

<>我想我记得我在看C++的Hans Bohen GC时,库将用GC版本替换NeX/DELT,但是你仍然必须把分配器传递给你想要使用的STL结构。
此外,您正在使用的库中可能有代码仍在使用malloc。需要考虑的一些问题。

\u M\u insert\u aux
位于
vector.tcc
中,这让人恼火,因为它与GCC的关系不太好。但是,快速扫描显示它与其他方法一样正确地调用了分配器

  pointer __new_start(this->_M_allocate(__len));

您可以尝试在
运算符new
中设置断点,定义一个自定义分配器(您可以从
std::allocator
派生),该分配器打印调试输出,或者在
new\u allocator.h:91
中设置断点,库应在此处调用您的覆盖。

最可能的解释是,GCC的std::vector内部实现包括新的。MSVC有许多额外的运算符新重载。您需要拆分源代码或创建新的自定义分配器。

我最终使用George Costanza的技术解决了我的问题:做相反的事情

我没有尝试使我的操作符成为新的并删除可见的内容,而是将它们完全隐藏起来

诀窍是在每个静态libs中设置它们&在bundle设置中:

  • C++标准库类型:静态
  • 默认情况下隐藏的符号:选中
  • 修复并继续:未选中(非常重要,否则会自动禁用以前的设置)
做一个干净的所有&构建,因为对于XCode 3.2,在更改这些设置后简单地点击构建将不起作用

显然,我将操作员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
不,为什么会这样?必须同时具有静态和隐藏符号才能工作。它似乎屏蔽了我的bundle插件,使其不受将其分配器内联的STL专门化实现的影响


还要注意,这只发生在从大型应用程序动态加载的捆绑插件中。在从控制台应用程序调用的普通.dylib项目中,任何设置都可以正常工作。

检查是否调用的更可靠的方法是在调用应用程序API之前插入断点。vector.tcc中的实现非常漂亮。事实上,在调试一个简单的控制台应用程序时,我能够分步编写这段代码。我不知道为什么GDB在调试.dylib时找不到源代码。