【问题标题】:C++: efficient swap() when using a custom allocatorC++:使用自定义分配器时的高效交换()
【发布时间】:2023-03-21 07:48:01
【问题描述】:

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

目前,我们定义了一个swap,它接受一个 std::string 作为参数:

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&amp; str) 现在不见了。此线程中对该函数的引用已保留以供后代使用。

杰夫

【问题讨论】:

  • 为什么要用 SecureString 交换 std::string?为什么不只提供 SecureString 与 SecureString 的交换?
  • @dalle:我们正在努力让用户更轻松。
  • 如果使用 SecureString 有任何好处,那么用 SecureString 交换字符串对我来说听起来像是一个非常不安全的操作。如果 SecureString 的目的是在释放之前清除内存,并且您将其内容交换为常规字符串,那么它们在释放之前不会被清除,因此无论可能发生什么坏事,您已经让它发生了。当然,数据应该很容易从字符串传输到 SecureString,但将其取回应该通过一些易于识别和审计数据安全的功能。
  • @Steve:你是对的。我正在考虑交换 std::string 的路线,而不是交换 SecureString 的路线。凯文可能会在审计中发现它。

标签: c++ templates swap


【解决方案1】:

不幸的是……没有。

这不是rebind 的用途。使用 rebind 是因为分配器旨在分配一种类型的对象,并且在 STL 中仅分配一种类型 (std::allocator&lt;T&gt;)。

但是,有一个技巧。比如当你实例化std::list&lt;T, std::allocator&lt;T&gt;&gt;,那么allocator不必分配Ts,它必须分配一些内部结构,而不是像__list_node&lt;T&gt;,也就是当rebind被使用时,它创建一个新的分配器,先例的兄弟(它们仅在模板参数上有所不同,并且可能共享相同的内存池)。

但是,在您的情况下,您的分配器和std::string 分配器是不同的,因此它们不能交换 内存。所以你必须复制一份。

你可以优化void swap(SecureString&amp;, SecureString&amp;)操作,但不能优化这个。

一个问题:为什么不typedef std::string&lt;char, SecureAllocator&lt;char&gt;&gt; SecureString;?

【讨论】:

  • 谢谢 - 我害怕那个。至于typedef,原来是typedef。但是,我们希望使用 std::strings 以方便用户使用。我不知道如何重载复制和赋值(等)以仅使用 typedef 来获取 std::string。
  • @noloader:确实不可能。与std::string 的直接交互将需要一个自定义类。我不确定是否提供此swap。
猜你喜欢
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 2019-08-11
  • 2014-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多