【问题标题】:How is stored a vector<string> in memory如何将 vector<string> 存储在内存中
【发布时间】:2016-01-12 22:14:54
【问题描述】:

我正在做一个项目,我绝对需要在内存中拥有连续的数据。 我想存储一些(最多 100 个)字符串(我不知道每个字符串的实际大小)。所以我将创建一个包含 100 个元素的字符串向量。

std::vector<std::string> vect;
vect.reserve(100)

但字符串可以是任意大小。那么它是怎样工作的?每次更改字符串时,我的向量都会重新分配吗?还是 std::string 就像指向字符串第一个字符的指针一样,就像 char* 将用于 C 字符串?

【问题讨论】:

  • std::string 在您的示例中表现得像一个指针。有小字符串优化,其中小字符串(小意味着〜20-40个字符)位于std::string本身内。如果您要求所有字符都在连续的内存中,则必须使用 vector&lt;char&gt; 并手动执行。
  • 谢谢,这种信息很珍贵,因为字符串可以做背景的事情,所以我才问这个。你说的是它做了一些优化,可能使它不连续?
  • A std::string 是动态分配的,并保证始终具有 local 连续内存(意味着单个字符串将具有连续内存)。但是,这并没有说明它在您的 vectstrings 中的连续性。我不知道以这种方式保证连续性的方法。
  • @cmbasnett std::string 的构造函数有一个std::allocator 的可选模板参数。您可以定义一个内存池,每次创建string 时都会在其中分配。您可以确保所有字符串都在一个连续的内存块中。

标签: c++ memory


【解决方案1】:
  1. 每个string 都是string 类的一个实例,并且该实例将包含一个char*
  2. 向量中的string 对象将位于连续内存中。
  3. 每个string 的字符将在连续内存中
  4. All 所有字符串的字符都不会在连续的内存中,除非您为字符串定义自定义std::allocator
  5. 当您增加vector 的大小或调用shrink_to_fit 时,字符串在内存中的位置可能会改变
  6. 当您增加string 的大小时,每个string 的字符在内存中的位置可能会发生变化
  7. 如果您修改或删除其中一个字符串,vector 将不会被重新分配
  8. 有一种叫做小字符串优化的东西。如果发生这种情况,每个string 的字符将存储在string 中,而不是char* 指向的另一个位置

【讨论】:

  • 所以字符串其实只是一个char*的封装
  • 它是模板化的,但如果你只使用默认的 std::string 那么是的。
  • @FreeYourSoul 它有更多的东西,比如容量和大小,而不仅仅是char *
【解决方案2】:

std::vector 中的数据是连续布局的。然而std::strings 实现并不能保证保存字符数组的内存在本地存储到类本身。怎么可能?就像你说的你不知道字符串会有多大。

很多类似数组的结构都有如下布局:

class string
{
    T * begin; 
    T * end;
    T * capacity;
}

这意味着您的 100 个字符串向量将有 100 个类布局实例,指向存储字符串的内存。

现在,如果您需要尽可能紧密地打包内存分配并且仍想使用std::string,您可以编写自定义allocator

也许您可以将字符串数据写入 char 数组,并拥有第二个容器来存储每个单独字符串的长度 + NULL 终止符。

【讨论】:

    【解决方案3】:

    string 的实现是实现定义的,实际上在某些编译器的不同版本之间发生了变化(例如从 gcc 4.9 到 5.0)。绝对不能保证连续 strings 中的 chars 在内存中是连续的,即使您使用自定义分配器

    所以如果你真的需要chars 在内存中是连续的,你必须只使用vector&lt;char&gt;

    【讨论】:

      猜你喜欢
      • 2021-09-13
      • 1970-01-01
      • 2011-02-12
      • 2016-04-17
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2013-05-07
      • 2021-06-18
      相关资源
      最近更新 更多