【问题标题】:Guarantees on C++ std::string heap memory allocation?C++ std::string 堆内存分配的保证?
【发布时间】:2021-11-06 16:34:08
【问题描述】:

我的主要目标是避免动态内存分配。

例如,我可以确定哪些 std::string 方法将/不会分配新的堆内存吗?

有没有办法禁止 std::string 实例进行新分配?

有标准的定长字符串类吗?

【问题讨论】:

  • 不,你不能确定。不,没有办法禁止它(好吧,除非你创建自己的分配器类,它实际上不分配任何东西)。不,没有标准的固定长度字符串类,但是自己制作一个很容易,也许包装std::array
  • 不,即使内部进行了小字符串优化,也没有任何保证。 std::string 是 std::basic_string 容器的别名。这个容器有分配器。您可以使用自制分配器定义自己的别名,该分配器不使用 malloc/new 分配堆内存,即从主函数或线程例程顶部声明的某个堆栈数组中获取内存。无论如何,它适用于一些琐碎的流程,更简单的程序需要 C++ 中的堆。
  • IMO 唯一可以保证(按标准?)的是空字符串(即"\0")不会分配,这本身非常有用。对短字符串优化的任何其他声明或依赖确实只是一个很好的细节,但它不是基本的。

标签: c++ memory-management dynamic-memory-allocation stdstring


【解决方案1】:

有没有办法禁止 std::string 实例进行新分配?

不,但是我们可以使用std::pmr::string,因为 c++17 (如果保证字符串足够小:说短于 16 字节,我们可能会受益 从最近版本 STLS 中的 std::string 的短字符串优化中,内存分配不会发生,但它是一个黑盒)

constexpr size_t kMaxLen = 256;
char buffer[kMaxLen] = {};
std::pmr::monotonic_buffer_resource pool{std::data(buffer),std::size(buffer)};
std::pmr::string vec{&pool};

// assert that we don't have a string with a length larger than kMaxLen - 1, or we will trigger heap memory allocations

有标准的定长字符串类吗?

不,但我们可以选择非标准库作为替代方案:

【讨论】:

    【解决方案2】:

    例如,我可以确定哪些 std::string 方法将/不会分配新的堆内存吗?

    不,标准不保证不分配。

    但是,您可以为std::basic_string 提供用户定义的分配器。如果您在自定义分配器中不使用动态分配,则不会有动态分配。

    有标准的定长字符串类吗?

    没有。

    【讨论】:

    • 是的。我也想过这个。可能是最好(唯一)的方式。
    • 没有标准保证不会发生分配的成员函数吗?例如。索引现有字符串不应重新分配。调整到更小的尺寸怎么样?还保证附加字符只需要记录 n 次重新分配;从那以后,大多数时候,附加一个不会重新分配(即使没有任何保证只是 which 附加会触发一个),等等。
    • @Peter-ReinstateMonica 从技术上讲,不能保证默认构造函数不会分配,所以如果你按保证去做,那么你从一开始就被卡住了。
    猜你喜欢
    • 1970-01-01
    • 2018-02-03
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 2011-07-26
    • 2020-11-04
    相关资源
    最近更新 更多