写入<int>容器末端以外的向量的索引

Writing to index of vector<int> beyond end of container

本文关键字:向量 索引 int lt gt 写入      更新时间:2023-10-16

为什么以下内容有效?我认为在矢量对象的末尾之外写入矢量对象的索引会导致分割错误。

#include <iostream>
#include <vector>
using namespace std;
int main() {
  vector<int> x(1);
  x[10] = 1;
  cout << x[10] << endl;
}

这意味着什么?有没有一种更安全的方法来初始化一个正好有n个元素的向量,并只写入这些元素?我应该一直使用push_back()吗?

实现std::vector的人可能很容易决定给它10或20个元素左右的最小大小,因为内存管理器可能有足够大的最小分配大小,它无论如何都会使用(大约)相同数量的内存。

至于避免读/写到最后,一种可能性是尽可能避免使用索引,当你真的无法避免时,使用.at()进行索引

我发现,通过对大多数任务使用基于范围的for循环和/或标准算法,我通常可以避免进行索引。对于一个微不足道的例子,可以考虑这样的东西:

int main() {
    vector<int> x(1);
    x.push_back(1);
    for (auto i : x)
        cout << i << "n";
}

.at()确实有效,但我很少觉得它有用或必要——我怀疑我平均每年使用它不到一次。

因此,当您试图寻址容器边界之外的数组或向量的元素时,实际发生的情况是对不属于容器的内存的内存解引用。然而,对这个位置的读写可以"起作用",也可以看起来起作用,因为你读写的只是更多的内存。你正在做一些非常非常糟糕的事情。当访问超出界限的内存时,您通常会看到随机垃圾,因为它可能属于其他东西,或者是前一个进程的剩余内存,因为内存控制器不会自动将内存清零。因此,如果您怀疑自己是否超出了容器的范围,最好的做法是使用容器的大小来检查您的读写操作。您可以使用vector.size()来查找容器的当前大小。