c++中关于std::vector的基本问题
basic question on std::vector in C++
c++教科书和线程都说vector元素在内存中是物理上连续的。
但是当我们做像v.push_back(3.14)
这样的操作时,我会假设STL使用new
操作符来获得更多的内存来存储刚刚引入向量的新元素3.14。
现在假设大小为4的向量存储在标记为0x7, 0x8, 0x9, 0xA
的计算机内存单元中。如果单元格0xB
包含一些其他不相关的数据,3.14
如何进入这个单元格?这是否意味着单元格0xB
将被复制到其他地方,擦除以为3.14
腾出空间?
简短的回答是,保存向量数据的整个数组被移动到一个有空间可以增长的位置。vector类保留了一个比技术上容纳vector中元素数量所需的更大的数组。例如:
vector< int > vec;
for( int i = 0; i < 100; i++ )
vec.push_back( i );
cout << vec.size(); // prints "100"
cout << vec.capacity(); // prints some value greater than or equal to 100
capacity()
方法返回vector所保留的数组的大小,而size()
方法返回数组中实际使用的元素的数量。capacity()
将始终返回一个大于或等于size()
的数字。您可以使用reserve()
方法来更改后备数组的大小:
vec.reserve( 400 );
cout << vec.capacity(); // returns "400"
注意,size()
、capacity()
、reserve()
和所有相关的方法都指向vector所保存的类型的单个实例。例如,如果vec
的类型参数T是一个占用10
字节内存的结构体,那么vec.capacity()
返回400
意味着该向量实际上保留了4000
字节的内存(400 x 10 = 4000
)。
那么,如果向vector中添加的元素超过了vector的容量,会发生什么情况呢?在这种情况下,vector分配一个新的后备数组(通常是旧数组大小的两倍),将旧数组复制到新数组中,然后释放旧数组。在伪代码:
if(capacity() < size() + items_added)
{
size_t sz = capacity();
while(sz < size() + items_added)
sz*=2;
T* new_data = new T[sz];
for( int i = 0; i < size(); i++ )
new_data[ i ] = old_data[ i ];
delete[] old_data;
old_data = new_data;
}
因此整个数据存储被移动到内存中的一个新位置,该位置有足够的空间来存储当前数据和一些新元素。
std::vector
首先分配一个更大的缓冲区,然后将"旧"缓冲区中的现有元素复制到"新"缓冲区中,然后删除"旧"缓冲区,最后将新元素添加到"新"缓冲区中。
一般来说,std::vector
实现通过每次需要分配更大的缓冲区时将容量增加一倍来增长它们的内部缓冲区。
正如Chris提到的,每次缓冲区增长时,所有现有的迭代器都会失效。
当std::vector为值分配内存时,它分配的内存比实际需要的要多;你可以通过调用capacity
来了解多少。当该容量用完时,它会分配一个更大的块,同样比它需要的大,并将所有内容从旧内存复制到新内存;然后释放旧内存
如果没有足够的空间来添加新元素,则会分配更多的空间(正如您正确指出的那样),并将旧数据复制到新位置。因此单元格0xB将仍然包含旧的值(因为它可能在其他地方有指向它的指针,不可能在不造成破坏的情况下移动它),但是有问题的整个向量将被移动到新位置。
vector是一种内存数组。典型的实现是它获取比所需更多的内存。如果该内存占用需要扩展到任何其他内存,那么整个内存都会被复制。旧的东西被释放了。向量内存在堆栈上——这一点应该注意。说明需要最大尺寸也是一个好主意。
在来自C的c++中,内存不是按照您描述的方式"管理"的- Cell 0x0B
的内容不会被移动。如果这样做,任何现有的指针都将无效!(唯一可能的情况是,该语言没有指针,只使用类似功能的引用。)
std::vector
分配了一个新的更大的缓冲区,并将3.14
的值存储到缓冲区的末尾。
通常,对于优化的this->push_back()
s, std::vector
分配的内存大约是this->size()
的两倍。这确保了以合理数量的内存交换性能。因此,不能保证3.14
会导致this->resize()
,当且仅当this->size() < this->capacity()
.
this->buffer[this->size()++]
。
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 替代在python中制作邻接列表与图形问题的字典?(如 C++ 中的 vector<vector<int&g
- C++ 中 std::vector 的内存问题
- 示例代码中使用分隔符将 std::string 拆分为 std::vector 的范围问题
- 错误 C2280 / 在 std::vector 中实例化对象时复制构造函数出现问题?
- 尝试使用初始值设定项列表构造"std::vector"的问题
- 英特尔编译器 (C++) 问题与 std::vector 上的 OpenMP 缩减
- 当我向 vector<int *> 添加元素时,我遇到了一些问题
- std::shared_ptr<std::vector有什么问题<double>>
- 带有 std::vector 和 std::queue 的 Prim's 算法,我的代码有什么问题?
- 有关std :: vector的QuickSort的问题
- C++ vector<pair<int,int>> std::all_of() 函数问题(重定向到头文件)
- C 内存管理问题,std :: vector nevere rase内存超出范围
- std::vector 和/或多态性的问题
- 在 std::vector 中使用结构来推送多个类型有什么问题?
- 使用OpenCV Vector和MATLAB时遇到问题
- 在使用 std::string 和 std::vector 将值插入 std::map 时遇到问题
- 用std::vector编写可调整大小的矢量时出现问题
- 清除并重新填充 std::vector<std::vector<T>>导致分配问题