简体   繁体   English

std :: vector连续的含义

[英]std::vector contiguous meaning

I've read in a lot of places like here that std::vector is always contiguous, but I didn't find an explanation to the meaning of this or why is this important? 我读了很多的地方,如在这里std::vector范围始终是连续的,但我没有找到一个解释这是什么意思,或者为什么这很重要?

Does this mean that they have a fixed place in memory or what? 这是否意味着他们在记忆中有固定的位置或者什么?

Contiguous in this context means that sequentially numbered vector's elements are located next to each other in memory space. 连续在此上下文中意味着顺序编号的矢量的元素被彼此相邻地位于存储器空间。 For example, if an element i is located at the address a , and has a size of s , then the element i+1 would be located at the address a+s , the element i+2 would be at a+s+s , and so on. 例如,如果元素i位于地址a ,并且其大小为s ,则元素i+1将位于地址a+s ,元素i+2将位于a+s+s , 等等。

This is important for two reasons: 这有两个重要原因:

  • Contiguous requirement makes random access possible - you can compute the location of any element based on vector's base address and element's index 连续需求使随机访问成为可能 - 您可以根据向量的基址和元素索引计算任何元素的位置
  • You can predict locality of reference - processing vector elements sequentially is the same as processing array elements sequentially for the purposes of cache behavior analysis. 您可以预测引用的位置 - 顺序处理向量元素与为了缓存行为分析而顺序处理数组元素相同。

The elements in a std::vector occupy a contiguous block of memory. std::vector的元素占用连续的内存块。 A std::vector is an improved array. std::vector是一个改进的数组。

This is important because it means access to an arbitrary element is fast. 这很重要,因为这意味着对任意元素的访问速度很快。 Because the size and number of elements is known, you can look up any element quickly. 由于元素的大小和数量是已知的,因此您可以快速查找任何元素。

The drawback is that any reorganization, such as inserting or deleting an element in the middle, is an expensive operation as it requires all others to be shuffled to maintain contiguity. 缺点是任何重组,例如在中间插入或删除元素,都是一项昂贵的操作,因为它需要对所有其他重组进行洗牌以保持连续性。

Other data structures such as lists allow easier reorganization with other tradeoffs. 其他数据结构(如列表)允许更容易的重组与其他权衡。

这意味着您始终可以通过指针算法获取下一个元素的地址。

It means that there are no holes in a std::vector 's internal memory representation. 这意味着std::vector的内存表示中没有空洞。 It looks like this in memory: 它在内存中看起来像这样:

内存中的<code> std :: vector </ code>

Each square represents an address in memory, and every orange one an element occupied by the vector. 每个方块表示内存中的地址,每个橙色方块表示向量占用的元素。

Most other containers are not contiguous. 大多数其他容器不连续。 For example, a std::forward_list looks like this in memory: 例如, std::forward_list在内存中看起来像这样:

内存中的<code> std :: forward_list </ code>

Here, again, the orange addresses contain the elements of the container. 同样,橙色地址包含容器的元素。 But they are scattered across memory. 但它们分散在记忆中。 There are also grey elements; 还有灰色元素; they represent the additional memory needed by the list so that each elements knows where the next element is found. 它们代表列表所需的额外内存,以便每个元素知道下一个元素的位置。 [*] [*]

As you can imagine, the clear and concise memory representation of std::vector gives you a lot of advantages. 可以想象, std::vector的清晰简洁的内存表示为您提供了很多优势。 It explains why std::vector has some operations other containers lack, or why those operations run in constant time. 它解释了为什么std::vector有一些其他容器缺少的操作,或者为什么这些操作在恒定时间内运行。 For example, in order to get to the n-th element, you just perform one addition (base address + n). 例如,为了获得第n个元素,您只需执行一次加法(基址+ n)。 It also explains why you can safely take &v[0] and perform pointer arithmetics on it. 它还解释了为什么你可以安全地使用&v[0]并在其上执行指针算术。


[*] This is a bit of a simplification, because the example has char elements, but the pointers in the list occupy more memory than single char s on typical C++ implementations. [*]这有点简化,因为该示例具有char元素,但是在典型的C ++实现中,列表中的指针占用的内存比单个char更多。 A more realistic diagram would use 4 or 8 grey squares for every element, because that's the size of one pointer on typical modern machines. 更现实的图表将为每个元素使用4或8个灰色方块,因为这是典型现代机器上一个指针的大小。

As none of the answers mentioned it: 由于没有一个答案提到它:

Thanks to this feature of std::vector you can do things like 感谢std::vector这个功能,你可以做类似的事情

std::ifstream file( "file.txt", std::ios::ate | std::ios::binary );
std::vector<char> vec;
if (!file)
{
    file.seekg(0, std::ios_base::end);
    auto fileSize = file.tellg();
    vec.resize(fileSize);

    file.seekg(0, std::ios_base::beg);

    // here we leverage contiguous memory in std::vector
    file.read(&vec[0], fileSize);
}

where you avoid reading/writing element by element. 在哪里避免逐个元素地读/写。

This can be used since C++03, as mentioned in the (C++03) standard (23.2.4.1) 这可以在C ++ 03中使用,如(C ++ 03)标准(23.2.4.1)中所述

The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool , then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size() . vector的元素是连续存储的,这意味着如果v是一个vector ,其中T是某种类型而不是bool ,那么它服从所有0 <= n < v.size()的身份&v[n] == &v[0] + n 0 <= n < v.size()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM