取消引用访问元素的向量指针

Mat*_*Mat 54 c++ vector dereference

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

vector<int>* vecPtr;
Run Code Online (Sandbox Code Playgroud)

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

int a = (*vecPtr)[i];
Run Code Online (Sandbox Code Playgroud)

但是这个解除引用会不会在堆栈上创建我的矢量副本?假设向量存储10000个int,是否会通过解除引用来复制vecPtr 10000 int?

谢谢!

ser*_*gtk 64

10000 int秒不会被复制.解除引用非常便宜.

为了说清楚你可以重写

int a = (*vecPtr)[i];
Run Code Online (Sandbox Code Playgroud)

vector<int>& vecRef = *vecPtr; // vector is not copied here
int a = vecRef[i];
Run Code Online (Sandbox Code Playgroud)

此外,如果您担心存储的整个数据vector将位于堆栈中而您使用vector<int>*而不是vector<int>为了避免这种情况:情况并非如此.实际上,堆栈上只使用了固定数量的内存(大约16-20个字节,具体取决于实现),与存储在中的元素数量无关vector.它vector自己分配内存并在堆上存储元素.

  • 哇,我从来不知道将引用作为数据类型(vector <int>&vecRef)是合法的.我一直认为这仅限于功能参数.这是一个很好的信息! (8认同)

Tod*_*lin 47

不,什么都不会被复制; 取消引用只是告诉你要来调用operator []的C++ 载体,而不是你的指针,vecPtr.如果你没有取消引用,C++会尝试寻找在std::vector<int>*类型上定义的operator [] .

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

通常,通过指针访问向量是一种痛苦,(*vecPtr)[index]语法很难(但更好vecPtr->operator[](index)).相反,你可以使用:

vecPtr->at(index)
Run Code Online (Sandbox Code Playgroud)

这实际上是检查范围,不像operator[],所以如果你不想支付价格来检查索引是否在边界内,你就会被困住(*vecPtr)[].