Я хочу заменить стандартный распределитель на более надежный распределитель (стандарт C ++ требует только проверки переполнения на vector :: resize). Различные распределители C ++, поставляемые со многими библиотеками, оказываются безрезультатными, когда получают отрицательные результаты самопроверки.
У меня есть доступ к более надежному распределителю. Распределитель ESAPI не только проверяет переполнение, но также имеет средства отладки, помогающие находить ошибки. http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h.
Есть ли стандартный способ заменить C ++ распределитель, используемый в программе, без особых усилий? Я также хочу обеспечить его замену в коде библиотеки, который может не иметь доступа к исходному коду.
В отличие от malloc
которая является библиотечной функцией, которая может быть заменена другой функцией с той же сигнатурой, std::allocator
является шаблоном класса, а код шаблона создается по мере необходимости и включается в код, который его использует. Некоторый стандартный код библиотеки уже будет скомпилирован в объектные файлы библиотеки и будет содержать инстанцированные std::allocator
код, который не может быть заменен Таким образом, единственный способ состоит в том, если стандартная библиотека предоставляет какой-то нестандартный способ заменить std::allocator
, К счастью, GCC libstdc ++ позволяет вам делать это, позволяя вам выбрать реализацию, используемую для std::allocator
когда GCC настроен и собран, с несколькими разные варианты
Не было бы слишком много работы, чтобы добавить распределитель ESAPI к источникам GCC в качестве одного из вариантов, а затем перестроить GCC, чтобы использовать этот распределитель в качестве базового класса std::allocator
обеспечение его реализации. Возможно, вам придется немного подправить код-распределитель ESAPI и, возможно, изменить libstdc ++ configure
сценарий, чтобы позволить вам сказать --enable-libstdcxx-allocator=esapi
В C ++ 0x определите новый псевдоним шаблона в пространстве имен mystd
это std::vector
но с вашим пользовательским распределителем. Заменить все std::vector
с mystd::vector
, Избавиться от всего using namespace std
а также using std::vector
в вашем коде.
Перестроить. Замените места, где вы использовали сырье vector<T>
с mystd::vector<T>
,
Да, и используйте лучшее имя, чем mystd
,
Если вы хотите изменить распределение на глобальном уровне, а не на контейнер, вы, вероятно, хотите заменить ::operator new
а также ::operator delete
, Возможно, вы также хотели бы заменить ::operator new[]
а также ::operator delete[]
также — но они используются только для выделения массивов, которые вы почти никогда не должны использовать (кроме, если это не было очевидно: нет, это не используется для выделения памяти для std::vector
несмотря на то, что он довольно похож на массив в некоторых отношениях).
Хотя попытки заменить большинство частей библиотеки запрещены, стандарт специально разрешает их замену.
Конечно, если кто-то уже указывает другой распределитель для конкретного контейнера, и этот распределитель (в конце концов) не получает свою память через ::operator new
(или же ::operator new[]
) это будет не повлиять на этот контейнер / эти контейнеры.