It seems to be the month of C++ templates for me...
I have a SecureString. SecureString looks just like a std::string, except it uses a custom allocator which zeroizes on destruction:
class SecureString
{
public:
typedef std::basic_string< char, std::char_traits<char>, zallocator<char> > SecureStringBase;
typedef zallocator<char>::size_type size_type;
static const size_type npos = static_cast<size_type>(-1);
....
private:
SecureStringBase m_base;
};
The full code for SecureString can be found at http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/SecureString.h; and the code for the allocator can be found at http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h.
Currently, we have a swap
defined that takes a std::string as an argument:
void SecureString::swap(std::string& str)
{
SecureStringBase temp(str.data(), str.size());
m_base.swap(temp);
str = std::string(temp.data(), temp.size());
}
I feel like I'm missing an opportunity in swap
because the underlying types only differ by allocators. Can anyone see a way to avoid the temporary? Is it possible to use rebind
to make this run faster?
EDIT: SecureString::swap(std::string& str)
is now gone. Reference to the function in this thread has been left in place for posterity.
Jeff
Unfortunately... no.
This is not what rebind
is for. rebind
is used because an allocator is meant to allocate objects of one type, and one type only (std::allocator<T>
) in the STL.
However, there is a trick. When you instantiate std::list<T, std::allocator<T>>
for example, then the allocator
does not have to allocate T
s, it has to allocate some internal structure instead like __list_node<T>
, and that is when rebind
is put to use, it creates a new allocator, sibling of the precedent (they differ only by the template parameter and likely share the same memory pool under the covers).
In your case however, your allocator and the std::string
allocator are different, and thus they cannot exchange memory. So you have to do a copy.
You can optimize the void swap(SecureString&, SecureString&)
operation, but not this one.
One question: why not typedef std::string<char, SecureAllocator<char>> SecureString;
?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With