指向访问元素的解引用向量指针

如果我在 C + + 中有一个指向向量的指针:

vector<int>* vecPtr;

我想要访问向量的一个元素,然后我可以通过解引用向量来做到这一点:

int a = (*vecPtr)[i];

但是这个解引用真的会在堆栈上创建一个向量的副本吗?假设向量存储10000整数,通过解引用 vecPtr 10000整数会被复制吗?

谢谢!

103062 次浏览

10000个 int将不会被复制。解引用是非常便宜的。

为了表明你可以重写

int a = (*vecPtr)[i];

作为

vector<int>& vecRef = *vecPtr; // vector is not copied here
int a = vecRef[i];

另外,如果您担心存储在 vector中的所有数据都将位于堆栈上,并且使用 vector<int>*而不是 vector<int>来避免这种情况: 事实并非如此。 实际上,堆栈上只使用固定数量的内存(根据实现的不同,大约为16-20字节) ,这与存储在 vector中的元素数量无关。 vector本身分配内存并在堆上存储元素。

不,不会复制任何内容; 解引用只是告诉 C + + 您想在 矢量上调用操作符[] ,而不是在 指针vecPtr上。如果没有解引用,C + + 将尝试查找在 std::vector<int>*类型上定义的操作符[]。

由于 operator[]是针对所有指针类型定义的,因此这可能会让人感到非常困惑,但它相当于偏移了指针,就好像它指向的是 vector<int>数组一样。如果您真的只在那里分配了一个向量,那么对于除 0之外的任何索引,表达式的计算结果都是对垃圾的引用,因此您将得到一个 Segfault 或者一些您意想不到的东西。

通常,通过指针访问向量是一件痛苦的事情,而且 (*vecPtr)[index]语法很笨拙(但是比 vecPtr->operator[](index)好)。相反,你可以使用:

vecPtr->at(index)

operator[]不同,这实际上是检查范围,所以如果您不想为检查 index 是否在范围内而付出代价,那么就只能使用 (*vecPtr)[]