C++中的向量是指针吗?

5

假设我们有一个向量v,并将其传递给函数f。

void f(vector<int> &v) {
    cout<<&v;
}

int main() {
    vector<int> v;
    v.push_back(10);  
    v.push_back(20);
    v.push_back(30);

    cout<<&v[0]<<"\n"<<&v<<"\n";
    f(v);
}

我得到的输出如下:

0x55c757b81300
0x7ffded6b8c70
0x7ffded6b8c70

我们可以看到&v&v[0]有不同的地址。那么v是指向向量开头的指针吗?如果是,为什么我无法访问*v?这里是否有错误?
谢谢。

你为什么想要以这种方式访问它?这就是迭代器的作用。 - tadman
这是参考。它们的内存位置。 - foragerDev
vector 是一个模板,vector<int> 是一个类,而 v[0] 则是一个 int。实现中是否使用指针是内部细节,未记录且不可依赖。你为什么要关心呢?最后两行打印相同地址是预期的,并且对于所有引用类型参数都是一样的。 - dxiv
请查看指针变量和引用变量之间的区别。 - foragerDev
1
关于std::vector类型的使用方法,建议查阅C++标准、好的书籍或者cppreference.com等资料。如果你很好奇,也可以尝试阅读std::vector模板的源代码,不过这对初学者来说可能有一些难度。作为一个新用户,在这里请从[tour]入手,并阅读[ask]。 - Ulrich Eckhardt
2
int *p = v.data(); cout<<p<<" "<<&v[0] 会得到相同的结果。&v 是 vector 对象的地址,而 &v[0] 是底层数组的地址。 - Ch3steR
4个回答

11

C++中的向量是指针吗?

不是。 std::vector 是一个类,不是指针。

那么v是指向向量开头的指针吗?

不是,但是vector类的实例v确实包含指向数组开头的指针。

为什么我无法访问 *v?

因为对于类 std::vector,不存在一元运算符 operator* 的重载。


那么如果我需要访问中间任何元素的地址,&v[i] 是我的唯一方法吗? - Rishab Balasubramanian
1
@RishabBalasubramanian,您不需要使用addressof运算符来访问元素。此外,下标运算符并不是访问元素的唯一方式。还有其他方法,例如使用指针或向量迭代器。 - eerorika

4

std::vector 结构体可能包含附加数据,例如长度。连续的元素存储在单独的位置,并且随着数组的重新调整而改变该位置。只要未移动 v&v 应保持不变,但是对于多种原因,&v[0] 可能会失效。

想象一下,非常大略地说:

struct vector {
  size_t size;
  T* elements;
};

operator[] 的实现是在使用 &v[0] 时启用的。

它不是指针,并且与 new[] 表现非常不同。


谢谢,我想我明白了。 - Rishab Balasubramanian

1

std::vector是一个封装动态大小数组的序列容器,因此它绝对不是指针。

正如@tadman所说,v(vector类的实例)确实包含指向数组开头的指针。

您无法访问*v,因为没有为std::vector类的一元运算符*重载。


0

不,C++ 中的向量不是指针。 向量是 C++ 中的一个类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接