std :: vector在内存中看起来像什么? [英] What does std::vector look like in memory?

查看:102
本文介绍了std :: vector在内存中看起来像什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到std::vector应该是连续的.我的理解是,它的元素应该存储在一起,而不是散布在整个内存中.我只是接受了这一事实,并在例如使用其data()方法获取底层连续内存时使用了该知识.

I read that std::vector should be contiguous. My understanding is, that its elements should be stored together, not spread out across the memory. I have simply accepted the fact and used this knowledge when for example using its data() method to get the underlying contiguous piece of memory.

但是,我遇到了一种情况,矢量的记忆以一种奇怪的方式表现:

However, I came across a situation, where the vector's memory behaves in a strange way:

std::vector<int> numbers;
std::vector<int*> ptr_numbers;
for (int i = 0; i < 8; i++) {
    numbers.push_back(i);
    ptr_numbers.push_back(&numbers.back());
}

我希望这能给我一些数字的向量和指向这些数字的指针的向量.但是,当列出ptr_numbers指针的内容时,会有不同的看似随机的数字,好像我正在访问错误的内存部分一样.

I expected this to give me a vector of some numbers and a vector of pointers to these numbers. However, when listing the contents of the ptr_numbers pointers, there are different and seemingly random numbers, as though I am accessing wrong parts of memory.

我试图检查每一步的内容:

I have tried to check the contents every step:

for (int i = 0; i < 8; i++) {
    numbers.push_back(i);
    ptr_numbers.push_back(&numbers.back());
    for (auto ptr_number : ptr_numbers)
       std::cout << *ptr_number << std::endl;
    std::cout << std::endl;
}

结果大致如下:

1

some random number
2

some random number
some random number
3

因此,当我push_back()访问numbers向量时,其较旧的元素似乎会更改其位置.

So it seems as though when I push_back() to the numbers vector, its older elements change their location.

那么std::vector是一个连续的容器到底是什么意思,为什么它的元素会移动?是否需要将它们存储在一起,但在需要更多空间时将它们一起移动?

So what does it exactly mean, that std::vector is a contiguous container and why do its elements move? Does it maybe store them together, but moves them all together, when more space is needed?

std::vector仅在C ++ 17之后才是连续的吗? (只是保持对我以前的主张的评论与未来的读者相关.)

Is std::vector contiguous only since C++17? (Just to keep the comments on my previous claim relevant to future readers.)

推荐答案

大致如下(请问我的MS Paint杰作):

It roughly looks like this (excuse my MS Paint masterpiece):

您在堆栈上的std::vector实例是一个小对象,其中包含指向堆分配的缓冲区的指针,以及一些额外的变量来跟踪向量的大小和容量.

The std::vector instance you have on the stack is a small object containing a pointer to a heap-allocated buffer, plus some extra variables to keep track of the size and and capacity of the vector.

因此,当我push_back()访问numbers向量时,其较旧的元素似乎会更改其位置.

So it seems as though when I push_back() to the numbers vector, its older elements change their location.

堆分配的缓冲区具有固定的容量.当您到达缓冲区的末尾时,会在堆上的其他位置分配一个新缓冲区,并且所有先前的元素都将被移到新的缓冲区中.因此,他们的地址将会更改.

The heap-allocated buffer has a fixed capacity. When you reach the end of the buffer, a new buffer will be allocated somewhere else on the heap and all the previous elements will be moved into the new one. Their addresses will therefore change.

是否可能将它们存储在一起,但是在需要更多空间时将它们一起移动?

Does it maybe store them together, but moves them all together, when more space is needed?

大概是的.只有在没有重新分配的情况下,std::vector 才能保证元素的迭代器和地址的稳定性.

Roughly, yes. Iterator and address stability of elements is guaranteed with std::vector only if no reallocation takes place.

我知道,std::vector是仅从C ++ 17起才是连续的容器

I am aware, that std::vector is a contiguous container only since C++17

std::vector的内存布局自其在标准版中首次出现以来就没有改变. ContiguousContainer 只是为了将连续容器与其他在编译时.

The memory layout of std::vector hasn't changed since its first appearance in the Standard. ContiguousContainer is just a "concept" that was added to differentiate contiguous containers from others at compile-time.

这篇关于std :: vector在内存中看起来像什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆