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

Posted

技术标签:

【中文标题】取消引用指向访问元素的向量指针【英文标题】:Dereference vector pointer to access element 【发布时间】:2010-12-27 00:17:19 【问题描述】:

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

vector<int>* vecPtr;

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

int a = (*vecPtr)[i];

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

谢谢!

【问题讨论】:

指向向量的指针并不常见——考虑一下你是否真的应该有一个引用或一个向量值。 这并不罕见,就生成的机器代码而言,对向量的引用与指向向量的指针完全相同。任何认为指针和引用之间有任何有意义区别的人都是在自欺欺人。 【参考方案1】:

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

为了清楚你可以重写

int a = (*vecPtr)[i];

作为

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

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

【讨论】:

哇,我从来不知道将引用作为数据类型(vector& vecRef)是合法的。我一直认为这仅限于函数参数。这是很好的信息! 如果你不把括号放在 (*vecPtr) 你会得到编译器错误: 错误: no match for 'operator*' (operand type is '...... 模板相关长文本未显示 很高兴知道。另一方面,vector&lt;int&gt; copied = *vecPtr; 似乎确实复制了整个向量。【参考方案2】:

不,不会复制任何内容;解除引用只是告诉 C++ 你想在 vector 上调用 operator[],而不是在你的 pointer 上,vecPtr。如果您没有取消引用,C++ 将尝试查找在 std::vector&lt;int&gt;* 类型上定义的 operator[]。

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

一般来说,通过指针访问向量很痛苦,(*vecPtr)[index] 的语法很尴尬(但比vecPtr-&gt;operator[](index) 好)。相反,您可以使用:

vecPtr->at(index)

这实际上检查范围,不像operator[],所以如果你不想为检查索引是否在范围内付出代价,你会被(*vecPtr)[]卡住。

【讨论】:

小的澄清。 operator[] 是为 std::vector* 定义的,因为 operator[] 是为任何指针定义的。但它没有按预期返回int,而是引用了std::vector,里面有垃圾,不能分配给int。 当想要将向量传递给期望const std::vector&lt;int&gt;&amp;作为参数的函数时,这是否适用? at 是否与按索引访问元素一样快?

以上是关于取消引用指向访问元素的向量指针的主要内容,如果未能解决你的问题,请参考以下文章

如何访问包含指向字符串的指针的向量的元素?

通过指针、强制转换和取消引用加载向量?

取消引用指针和访问数组元素之间的区别

访问指向多维向量的指针向量中的元素

如何从 C++ 中的“指向对象的指针”向量访问对象

访问指向对象指针向量的指针的第一个元素?