问题
I want to replace the standard allocator with a more robust allocator (the C++ standard only requires an overflow check on vector::resize). The various C++ allocators supplied with many libraries fall flat on their face when fed negative self tests.
I have access to a more robust allocator. ESAPI's allocator not only checks for overflow, it also has debug instrumentation to help find mistakes. http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h.
Is there a standard way to replace the C++ allocator used in a program without too much effort? I also want to ensure its replaced in library code, which I may not have access to source code.
回答1:
Unlike malloc
which is a library function that can be replaced by another function with the same signature, std::allocator
is a class template and template code is instantiated as needed and inlined into code that uses it. Some standard library code will have already been compiled into the library's object files and will contain instantiated std::allocator
code which can't be replaced. So the only way is if the standard library provides some non-standard way to replace its std::allocator
. Luckily, GCC's libstdc++ allows you to do just that, allowing you to select the implementation used for std::allocator
when GCC is configured and built, with a few different choices
It wouldn't be too much work to add the ESAPI allocator to the GCC sources as one of the options, then rebuild GCC to use that allocator as the base class of std::allocator
providing its implementation. You might need to tweak the ESAPI allocator code a bit, and maybe alter the libstdc++ configure
script to allow you to say --enable-libstdcxx-allocator=esapi
回答2:
In C++0x, define a new template alias in namespace mystd
that is a std::vector
but with your custom allocator. Replace all std::vector
s with mystd::vector
. Get rid of all using namespace std
and using std::vector
in your code.
Rebuild. Replace the places where you used a raw vector<T>
with mystd::vector<T>
.
Oh, and use a better name than mystd
.
回答3:
If you want to modify allocation on a global basis instead of per-container, you probably want to replace ::operator new
and ::operator delete
. Conceivably, you'd also want to replace ::operator new[]
and ::operator delete[]
as well -- but these are only used for allocating arrays, which you should almost never use anyway (aside, in case it wasn't obvious: no, these are not used to allocate memory for a std::vector
, despite its being rather similar to an array in some ways).
Although trying to replace most parts of the library is prohibited, the standard specifically allows replacing these.
Of course, if somebody is already specifying a different allocator for a particular container, and that allocator doesn't (eventually) get its memory via ::operator new
(or ::operator new[]
) this will not affect that container/those containers.
来源:https://stackoverflow.com/questions/13263796/replace-standard-c-allocator