C++:使用自定义分配器时高效的 swap()

发布于 2024-12-03 02:19:35 字数 1385 浏览 0 评论 0 原文

对我来说,这似乎是 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

盗琴音 2024-12-10 02:19:35

不幸的是……没有。

这不是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 the allocator does not have to allocate Ts, 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; ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文