如果我在C ++中有一个指向向量的指针:
vector<int>* vecPtr;
我想访问矢量的一个元素,然后我可以通过去除矢量来做到这一点:
int a = (*vecPtr)[i];
但是这个解除引用会不会在堆栈上创建我的矢量副本?假设向量存储10000个int,是否会通过解除引用来复制vecPtr 10000 int?
谢谢!
答案 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)[]
。