替换标准C++分配器?

10
我想用一个更健壮的分配器来替换标准分配器(C++ 标准仅要求 vector::resize 上进行溢出检查)。许多库提供的各种 C++ 分配器,在负自测方面表现不佳。
我可以访问一个更健壮的分配器。ESAPI 的分配器不仅检查溢出,而且还具有调试工具以帮助查找错误。http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h
是否有一种标准的方法可以在程序中替换使用的 C++ 分配器,而不需要太多的努力?我还要确保它被替换到库代码中,这些代码可能无法访问源代码。

1
据我所知,所有标准容器构造函数都接受可选的分配器。 - chris
2
是的。我如何在不访问每个源文件中的每个声明的情况下全面替换它? - jww
如果声明是一致的,我相信有一些正则表达式可以很容易地完成它。即使不是这样,你也可以考虑特定的不一致性。 - chris
我想我正在寻找一个类似于“SetNewAndDelete”之类的东西...... - jww
3个回答

6
与可以被另一个具有相同签名的函数替换的库函数malloc不同,std::allocator是一个类模板,模板代码会在需要时被实例化并内联到使用它的代码中。一些标准库代码已经编译成库文件的目标文件,并包含了无法替换的已实例化的std::allocator代码。所以唯一的方法就是如果标准库提供了一些非标准的方式来替换它的std::allocator。幸运的是,GCC的libstdc++允许你这样做,允许你在配置和构建GCC时选择用于std::allocator的实现,提供其实现的基类为ESAPI分配器,有几个不同的选择
将ESAPI分配器作为选项之一添加到GCC源代码中并重新构建GCC以使用该分配器作为std::allocator的基类提供其实现并不需要太多工作。您可能需要微调ESAPI分配器代码,或者修改libstdc++的configure脚本以允许您说--enable-libstdcxx-allocator=esapi

很酷,谢谢Jonathan。"你可能需要稍微调整ESAPI分配器代码" - 考虑到你已经帮助我们这么多,如果不需要任何调整,我也不会感到惊讶。 - jww

5
如果您想要全局修改分配而不是每个容器,那么您可能需要替换::operator new::operator delete。也许,您还想替换::operator new[]::operator delete[],但这些仅用于分配数组,您几乎永远不应该使用它们(顺便说一下,如果这不明显:不,这些不是用于为std::vector分配内存的,尽管在某些方面它类似于数组)。
虽然禁止替换库的大多数部分,但标准特别允许替换这些部分。
当然,如果有人已经为特定容器指定了不同的分配器,并且该分配器没有通过::operator new(或::operator new[])获得其内存,那么这将不会影响该容器/那些容器。

谢谢Jerry。我认为对于像分配器这样简单的东西,没有简单的方法来做到这一点。我知道没有办法轻松处理所有不同的元素插入点。我已经准备好在我控制下的代码库中禁止STL代码的使用(我希望有一个安全意识的替代品)。 - jww
供以后参考,这里是如何替换运算符的方法。如果没有额外的注意事项,似乎非常简单。 - eonil

4
在C++0x中,定义一个新的模板别名在命名空间mystd。这个别名是一个std::vector,但使用你自定义的分配器。将所有std::vector替换为mystd::vector。在代码中去掉所有using namespace stdusing std::vector
重新构建。用mystd::vector<T>代替原来使用裸指针vector<T>的地方。
哦,还要使用比mystd更好的名称。

std::allocator是否是弱链接的?我能否通过提供一个强链接符号来绕过它? - jww
这是一个模板,而不是可以链接的符号。 - n. m.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接