无法访问堆上的向量

Can't access vector on the heap

本文关键字:向量 访问      更新时间:2023-10-16

我在堆中有一个向量,但无法获取其元素 - 它不编译 - 给出 n 错误"无法绑定"std::basic ostream" 堆栈向量和简单数组工作正常。 这是怎么回事?

#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> * factors= new vector<int>(4);
cout<<factors<<endl;
cout<<(factors+1)<<endl;
//cout<<factors[1]<<endl;
factors->push_back(12);
factors->push_back(232);
factors->push_back(54);
factors->push_back(42);
//cout<<*factors; //error - cannot bind 'std::ostream..' lvalue to 'std::basic_ostream...'
// cout<<factors[0]; // error
//vector in stack
vector<int> factors3(4);
factors3.push_back(43);
factors3.push_back(543);
factors3.push_back(64);
factors3.push_back(26);
cout<<"factors3 "<<factors3[3]<<endl; //gives "0"
cout<<"factors3 "<<factors3.at(3)<<endl; //gives "0"
int * factors2=new int[10];
factors2[0]=32;
factors2[1]=35;
factors2[2]=676;
factors2[3]=123;
cout<<factors2[0]<<endl; //it's OK
cout<<factors2[1]<<endl;
cout<<*factors2<<endl;
cout << "Done" << endl;
return 0;
}

让我们看一下导致编译器错误的行。首先,这个:

cout << *factors << endl;

在这里,factors是一个vector<int>*,所以*factors是一个vector<int>。因此,此代码尝试将vector<int>插入流中。您不能使用<<运算符在 C++ 中显示vector<int>(它不附带重载的<<运算符),因此您在此处得到的编译器错误意味着"我看到您正在尝试使用<<输出vector,但我不知道该怎么做。

那么,您可能想知道为什么代码

cout << *factors2 << endl;

工作正常。在这种情况下,factors2是一个int*,所以当你通过写*factors2来取消引用factors2时,你会得到一个实际的诚实到善良的整数,它确实可以打印出来。请注意,原始数组和vector在这方面的工作方式不同 - 在C++中,指向数组的指针只是指向数组第一个元素的指针,因此取消引用它们会生成指向第一个元素的指针,而指向vector的指针与指向其第一个元素的指针不同。

这也解释了为什么写作

cout << factors[0] << endl;

不行。记住 -factors是指向vector的指针,而vector不是数组。写factors[0]的意思是"给我factors指向的数组中的第一个vector",而不是"给我factors指向的vector的第一个元素"。如果这是你想做的,你可以写

cout << (*factors)[0] << endl;

这表示"取消引用factors以获取实际vector,然后查找其第0个元素。

至于你的第二个问题 - 为什么你没有看到你添加到向量中的数字? - 请注意,你通过编写声明了向量

vector<int> factors3(4); // <--- Notice the 4

这里的(4)的意思是"给我一个初始化为四个intvector,所有都是零。然后使用push_back时,您将向vector添加新元素,而不是替换现有元素。您可以通过直接写入矢量元素来解决此问题:

vector<int> factors3(4);
factors3[0] = 43;
factors3[1] = 543;
factors3[2] = 64;
factors3[3] = 26;

或者不指定factors3的大小:

vector<int> factors3; // <--- No 4!
factors3.push_back(43);
factors3.push_back(543);
factors3.push_back(64);
factors3.push_back(26);

或者,如果你有一个现代编译器,通过像这样初始化向量:

vector<int> factors3 = {43, 545, 64, 26};

无论哪种说法,您都在混合和匹配两种不同的方法 - 每种方法都可以单独工作 - 但这两种方法一起不能完成您期望它们做的事情。

总结一下:

  • 您可以取消引用指向数组的指针以获取指向第一个元素的指针,但这不适用于指向向量的指针。
  • 小心默认调整矢量大小,然后使用push_back- 这是一个容易犯的错误。
cout<<(factors+1)<<endl;
//cout<<factors[1]<<endl;

应该是:

cout << (*factors)[1] << endl;

vector<int> factors3(4);
factors3.push_back(43);
factors3.push_back(543);
factors3.push_back(64);
factors3.push_back(26);
cout<<"factors3 "<<factors3[3]<<endl; //gives "0"
cout<<"factors3 "<<factors3.at(3)<<endl; //gives "0"

因为你创建了一个包含 4 个元素的向量,然后又推送了 4 个元素,所以你最终会得到一个包含元素的向量0, 0, 0, 0, 43, 543, 64, 26