gpt4 book ai didi

c++ - vector 第一个指针的变化

转载 作者:太空狗 更新时间:2023-10-29 20:18:26 26 4
gpt4 key购买 nike

当我使用 vector 存储一些数据时,我通常通过 vector 第一个条目的指针访问这些数据。因为它比 at() 方法更快。但是我意识到当我插入一个数据 block 时,比如一个数组到 vector 的末尾,第一个条目的指针会发生变化。这可能与堆叠的东西有关,但是如果我通过 push_back 一次向数组添加一个元素,第一个指针不会改变。那是为什么呢?我应该担心使用指针访问元素吗?

这里是一个示例代码,供那些想要 checkout 的人使用:

int arrayLen = 500000;
vector<int> vint = vector<int>(2000,0);
int * firstEntry = &vint[0];

int * iarray = new int[arrayLen];
for(int i = 0; i< arrayLen; i++)
{
iarray[i] = i;
}
vint.insert(vint.end(),iarray,iarray+arrayLen);
cout << firstEntry << "," << &vint[0] << endl; // They ar not equal;

// reset the vector
vint.clear();
vint.resize(2000,0);
firstEntry = &vint[0];

for(int i = 0; i< arrayLen; i++)
{
vint.push_back(iarray[i]);
if(firstEntry != &vint[0])
cout << firstEntry << "," << &vint[0] <<","<< i << endl;
}// nothing is written

cout << firstEntry << "," << &vint[0] << endl; // now they are equal;

最佳答案

std::vector 可以动态调整大小。它这样做的方式是保留比需要更多的空间。一旦达到保留容量,就需要保留更大的数据 block (取决于实现,但新 block 的容量通常是之前大小的两倍)。然后将数据复制到新位置,这就是第一个元素的地址发生变化的原因。

只要您不向 vector 中添加更多数据,就不必担心指向 vector 中数据的指针失效。您可以通过检查 vint.capacity()==vint.size() 来预测进一步的 push_back() 何时会触发调整大小。您还可以通过 &vint[0](或 &vint.at() 获取范围检查)始终使用最新指针而不是复制它来避免使用无效指针。

如果您知道要插入许多新项目,则可以通过使用 reserve() 预分配空间来确保您有足够的容量(如果当前容量小于请求的容量)。但请注意,您不想零碎地做这件事 - 例如

vint.reserve(vint.size() + 2000);
for(int i=0; i<2000; ++i) {
vint.push_back(i);
}

会很好,但是

for(int i=0; i<2000; ++i) {
vint.reserve(vint.size() + 1);
vint.push_back(i);
}

这会拖累性能,因为您反复要求操作系统提供更多内存,并且每次迭代都会引发越来越大的复制操作。

关于c++ - vector 第一个指针的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4013261/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com