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

时间:2009-12-15 22:02:09

标签: c++ vector dereference

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

vector<int>* vecPtr;

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

int a = (*vecPtr)[i];

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

谢谢!

2 个答案:

答案 0 :(得分:58)

10000 int s将不会被复制。解除引用非常便宜。

要说清楚你可以重写

int a = (*vecPtr)[i];

as

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

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

答案 1 :(得分:44)

不,什么都不会被复制;解除引用只是告诉C ++您要在向量上调用operator [],而不是在指针vecPtr上调用。如果您没有取消引用,C ++将尝试查找std::vector<int>*类型上定义的operator []。

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

通常,通过指针访问向量很痛苦,而(*vecPtr)[index]语法很笨拙(但优于vecPtr->operator[](index))。相反,您可以使用:

vecPtr->at(index)

这实际上会检查范围,与operator[]不同,所以如果您不想为检查索引是否在边界内付出代价,那么您就会遇到(*vecPtr)[]