对我来说,这似乎是 C++ 模板月...
我有一个 SecureString。 SecureString 看起来就像 std::string 一样,只不过它使用自定义分配器,该分配器在销毁时归零:
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;
};
SecureString 的完整代码可以在 http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/SecureString.h;分配器的代码可以在 http://code.google.com/p/owasp-esapi-cplusplus/source/browse/trunk/esapi/util/zAllocator.h。
目前,我们定义了一个以 std::string 作为参数的 swap
:
void SecureString::swap(std::string& str)
{
SecureStringBase temp(str.data(), str.size());
m_base.swap(temp);
str = std::string(temp.data(), temp.size());
}
我觉得我错过了 swap
的机会,因为底层类型仅在以下方面有所不同:分配器。任何人都可以找到避免暂时的方法吗?是否可以使用rebind
来使其运行得更快?
编辑: SecureString::swap(std::string& str)
现已消失。对该线程中函数的引用已保留给后代。
杰夫
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
发布评论
评论(1)
不幸的是……没有。
这不是
rebind
的用途。使用rebind
是因为分配器旨在分配一种类型的对象,并且在STL中仅分配一种类型(std::allocator
)。然而,有一个技巧。例如,当您实例化
std::list>
时,allocator
不必分配Ts,它必须分配一些内部结构,例如 __list_node
,也就是说,当使用rebind
时,它会创建一个新的分配器,先例的兄弟(它们仅在模板参数上有所不同,并且可能在幕后共享相同的内存池)。然而,在您的情况下,您的分配器和 std::string 分配器是不同的,因此它们不能交换内存。所以你必须复制一份。
您可以优化
void swap(SecureString&, SecureString&)
操作,但不能优化此操作。一个问题:为什么不
typedef std::string>安全字符串;
?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 theallocator
does not have to allocateT
s, it has to allocate some internal structure instead like__list_node<T>
, and that is whenrebind
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;
?