2015-04-02 2 views
3

У меня есть критический код безопасности, и я бы хотел убедиться, что чувствительные буферы всегда удаляются, прежде чем освободиться. Я могу реализовать класс буфера, который вызывает memset_s в своем деструкторе, но, возможно, есть более удобный способ.std :: vector с распределителем memset_s

Если я заменил std :: allocator на вариант, который вызывает memset_s в deallocate(), это заставит std :: vector не выделять объекты T нигде, кроме как временные?

Спасибо.

+0

Вероятно, интерес: HTTP : //stackoverflow.com/a/5735744/16287 –

+0

Да, по причинам, которые лучше всего объясняются [здесь] (http://stackoverflow.com/questions/8190950/may-stdvector-make-use-of-small-buffer-optimization). – MSalters

+0

Как насчет 'allocate_shared' или какого-либо варианта [' allocate_unique'] (http://stackoverflow.com/a/23132307/596781)? –

ответ

2

Существует две причины, по которым у вас могут быть такие объекты T: либо как элементы вектора, либо по другим причинам.

Они не могут быть элементами вектора, поскольку это нарушает смежность, а также нарушает гарантию отсутствия броска для swap. Если у вас есть элементы по другим причинам, они должны быть построены с заметной сложностью. Кроме того, T::T() может быть недоступен (DefaultConstructable не требуется), или он может выбросить, что также будет наблюдаемым эффектом.

Таким образом, вообще vector не может иметь «скрытые» элементы.

+0

'vector' может создавать локальные переменные' value_type'. Это делается, например, в одноэлементных функциях 'insert' и' emplace', возможно, чтобы включить вставку элемента, когда параметр (ы) функции имеет псевдоним текущего буфера, и необходимо изменить размер буфера. – dyp

+0

@ dyp: Правда, они могут существовать во время этих вызовов. Как только функция вернется, они должны исчезнуть. Это может работать, потому что 'T' должен быть CopyConstructable. Возможно, не буквально временный, но достаточно близкий к одному. – MSalters

2

Распределителя является аргументом шаблона, если вы решите реализовать один для вашего конкретного случая использования он будет действовать только в тех объектах, для которых явно выбираете в этот распределитель:

std::vector<T,SecureAllocator> v; // this uses the memset_s under the hood 
std::vector<T>     n; // this doesn't 

Теперь, распределяющий изменяет тип объекта, а это означает, что если у вас есть функции, которые принимают std::vector<T> в качестве аргументов, вы не сможете передать std::vector<T,SecureAllocator>.

В качестве альтернативы вы можете реализовать полиморфный распределитель, в котором можно управлять источником памяти во время выполнения. Это поддерживается в BSL (реализации на C++ 03 стандартной библиотеки доступны в GitHub), в этом случае векторы того же типа, даже если они выделяют из разных источников:

bsl::vector<T> v(bslma::Default::allocator()); 
    // bslma::Default::allocator() is new/delete 
bsl::vector<T> n(secureAllocator()); 
Смежные вопросы