C++ 向量是如何存储的<;字符串>;记忆中

C++ 向量是如何存储的<;字符串>;记忆中,c++,memory,C++,Memory,我正在做一个项目,我绝对需要在内存中有连续的数据。 我想存储一些(最多100个)字符串(我不知道每个字符串的实际大小)。我将创建一个由100个元素组成的字符串向量 std::vector<std::string> vect; vect.reserve(100) std::vector-vect; 车辆储备(100) 但是字符串可以是任意大小的。那么它是如何工作的呢?每次更改字符串时是否重新分配向量?或者std::string就像指向字符串第一个字符的指针一样,就像char*代表C

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

std::vector<std::string> vect;
vect.reserve(100)
std::vector-vect;
车辆储备(100)
但是字符串可以是任意大小的。那么它是如何工作的呢?每次更改字符串时是否重新分配向量?或者std::string就像指向字符串第一个字符的指针一样,就像char*代表C字符串一样

  • 每个
    string
    都是类
    string
    的实例,该实例将包含一个
    char*
  • 向量中的
    字符串
    对象将位于连续内存中
  • 每个
    字符串的字符将位于连续内存中
  • 除非为字符串定义自定义
    std::分配器
    ,否则所有字符串的所有字符都不会在连续内存中
  • 当您增大
    向量的大小或调用
    收缩以适应
  • 当您增大
    字符串的大小时,每个
    字符串的字符在内存中的位置可能会改变
  • 如果修改或删除其中一个字符串,
    向量
    将不会重新分配
  • 有一种叫做小字符串优化的方法。如果这起作用,则每个
    字符串
    的字符将存储在
    字符串
    中,而不是
    字符*
    指向的另一个位置

  • std::vector
    中的数据是连续排列的。但是,
    std::string
    s实现不能保证保存字符数组的内存本地存储到类本身。怎么可能呢?就像你说的,你不知道绳子有多大

    许多类似阵列的结构具有如下布局:

    class string
    {
        T * begin; 
        T * end;
        T * capacity;
    }
    
    这意味着100个字符串的向量将有100个类布局实例,这些实例指向存储字符串的内存

    现在,如果您需要尽可能紧密地打包内存分配,并且仍然希望使用
    std::string
    ,那么您可以编写一个自定义的


    也许您可以将字符串数据写入char数组,并使用第二个容器存储每个字符串的长度+空终止符。

    字符串的实现是实现定义的,并且在某些编译器的不同版本(例如从gcc 4.9到5.0)之间实际发生了更改。绝对不能保证连续
    字符串中的
    char
    s在内存中是连续的,即使使用自定义分配器也是如此


    因此,如果您确实需要
    字符
    在内存中是连续的,那么您必须只使用
    向量

    std::string
    在您的示例中的行为类似于指针。在
    std::string
    本身内部存在小字符串优化(小字符串指约20-40个字符)。如果您要求所有字符都在连续内存中,则必须使用
    向量
    ,并手动执行。谢谢您,此类信息非常宝贵,因为字符串可以执行背景操作,这就是我提出此问题的原因。您所说的是,它进行了一些优化,可能会使其不连续。
    std::string
    是动态分配的,并且保证始终具有本地连续内存(这意味着单个字符串将具有连续内存)。然而,这并没有说明它在
    string
    s的
    vect
    中的连续性。我不知道用这种方式保证连续性的方法。@cmbasnett
    std::string
    的构造函数有一个可选的模板参数,用于
    std::allocator
    。您可以定义一个内存池,每次创建
    字符串时,它都会被分配到内存池中。您可以确保所有字符串都在一个连续的内存块中。因此,字符串实际上只是一个字符的封装*它是模板化的,但如果您只使用默认的std::string,那么就可以了。@FreeYourSoul它有更多的容量和大小,而不仅仅是
    字符*