【问题标题】:Is an array of vectors entirely contiguous memory?向量数组是完全连续的内存吗?
【发布时间】:2014-09-26 01:09:48
【问题描述】:

我知道向量保证是连续的内存,数组也是如此。那么当我这样做时会发生什么:

std::vector<uint8_t> my_array[10];
my_array[2].push_back(11);
my_array[2].push_back(7);

记忆会是什么样子?如果两者都需要是连续的,那么每次我在my_array[2] 上执行push_back() 时,my_array[2] 之后的数组的每个元素都会向前推一个字节吗?

这是否与我有一个结构数组时的情况相同,其中结构具有可变大小的成员,例如字符串或另一个向量?

【问题讨论】:

    标签: c++ arrays memory


    【解决方案1】:

    向量内存结构在内存中是连续的;但是 std::vector 都包含一个指向动态分配内存的指针,用于实际存储(这很可能不连续)。

    知道这一点后,std::vector::push_back 将只检查(外部)动态分配的数组是否有足够的容量来容纳新项目,如果没有,它将重新分配空间。溢出的第一个向量上的 push_back 不会导致数组中的第二个向量重新分配内存,这不是它的工作原理。

    此外,没有可变大小的结构,结构和类的大小必须在编译时知道。

    std::string 也有一个固定的大小,虽然你可能认为它是可变的,因为它也(像向量一样)有一个指向它所包含的char* 的指针。

    【讨论】:

    • 我明白了。从“std::vector 都包含一个指向实际存储的动态分配内存的指针(这很可能不连续)”,您的意思是两个向量的存储不一定彼此连续,对吗?因为即使在堆中,单个向量的存储也应该是完全连续的,对吧?
    • 是的,单个向量的存储在堆中始终是连续的。但是,如果您在内存中有 2 个 std::vector 相互对齐,则它们的存储指针很可能不连续。
    【解决方案2】:

    std::vector 的内存占用由两部分组成:

    • std::vector 对象本身的内存(非常小,与大小无关),以及
    • 向量数据的内存(取决于向量中的元素数量)。

    第一种数据在数组中是连续的;第二种数据是动态分配的,所以在数组中不会是连续的。

    这与具有灵活数据成员的 C struct 不同,因为 std::vector 的数据部分并不总是分配在同一种内存中,更不用说与它相邻了。向量本身可以分配在静态、动态或自动内存区域中,而其数据始终在动态区域中。此外,当向量调整大小时,其数据的内存可能会移动到不同的区域。

    每次调用push_back 时,std::vector 都会检查它是否有足够的动态内存来容纳下一个数据元素。如果没有足够的内存,则向量会分配更大的内存块,并在推送新项目之前将其当前内容移动到那里。

    【讨论】:

    • 我明白了。如果我有一个包含字符串成员的结构数组会发生什么?字符串没有您描述的相同足迹,是吗?也就是说,字符串对象实际上保存了数据。
    • @Daniel 虽然标准没有说明字符串情况下需要发生什么,但实现通常与向量相同。有些实现将短字符串(几个字符)的数据保存在字符串本身中,但对于较长的字符串,所有实现都使用动态内存存储。 std::array 保持其数据内联,但您必须在编译时指定其大小。
    猜你喜欢
    • 2012-07-09
    • 2021-04-05
    • 2011-12-10
    • 2011-07-02
    • 2010-09-19
    • 2020-09-26
    • 1970-01-01
    • 2011-11-28
    • 2015-01-18
    相关资源
    最近更新 更多