73

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

vector<int>* vecPtr;

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

int a = (*vecPtr)[i];

但是这种取消引用实际上会在堆栈上创建我的向量的副本吗?假设向量存储 10000 个整数,是否会通过取消引用 vecPtr 10000 个整数被复制?

谢谢!

4

2 回答 2

89

10000int秒不会被复制。取消引用非常便宜。

为了清楚起见,您可以重写

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本身分配内存并将元素存储在堆上。

于 2009-12-15T22:10:14.287 回答
54

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

这可能会让人非常困惑,因为operator[]它是为所有指针类型定义的,但它相当于偏移指针,就好像它指向一个vector<int>. 如果你真的只在那里分配了一个向量,那么对于除 之外的任何索引0,表达式的计算结果都是对垃圾的引用,所以你会得到一个段错误或你没想到的东西。

一般来说,通过指针访问向量很痛苦,(*vecPtr)[index]语法也很笨拙(但比 更好vecPtr->operator[](index))。相反,您可以使用:

vecPtr->at(index)

这实际上会检查范围,operator[](*vecPtr)[].

于 2009-12-15T22:10:29.790 回答