我试图通过x坐标读取一个点列表到一个向量中。但是,我不断得到最后一个元素的向量。 例如,如果输入是
1 1
2 2
3 3
输出
3 3
3 3
3 3
这是我的代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
int x;
int y;
};
typedef Point* ppt;
int main()
{
//read input
int n;
cin >> n;
vector<ppt> v;
for(int i = 0; i < n; i ++){
Point p;
ppt pp = &p;
cin >> pp->x;
cin >> pp->y;
v.push_back(pp);
}
for(int i = 0; i < n; i ++){
ppt p = v.at(i);
cout << p->x << " " << p->y << endl;
}
return 0;
}
我阅读了文档。如果我理解正确的话,vector :: push_back(pp)会复制指针并在v的末尾插入复制的值。那么问题出在哪里?
答案 0 :(得分:3)
您的代码具有未定义的行为,因为此处
ppt p = v.at(i);
cout << p->x << " " << p->y << endl;
您正在尝试访问已经被破坏的对象:
{
Point p;
ppt pp = &p;
cin >> pp->x;
cin >> pp->y;
v.push_back(pp);
} // p is destructed here, so you have a dangling pointer in the vector
而不是使用Point
的指针向量使用std::vector<Point>
并添加对象而不是指针:
std::vector<Point> v;
//...
Point p;
cin >> p.x;
cin >> p.y;
v.push_back(p);
答案 1 :(得分:3)
for(int i = 0; i < n; i ++){
Point p;
ppt pp = &p;
cin >> pp->x;
cin >> pp->y;
v.push_back(pp);
}
此代码错误,您在for循环内部构造对象Point p
,但是当您在for循环上运行时,对象Point p
将被破坏,但是您将Point p
的地址存储到向量中,在对象Point p
被破坏后,向量中的内容无效。
你可以这样做:
for(int i = 0; i < n; i ++){
ppt pp = new Point();
cin >> pp->x;
cin >> pp->y;
v.push_back(pp);
}
答案 2 :(得分:0)
在第一个循环的每次迭代中,你创建了一个Point
类型的变量和一个指向它的指针,但是在这个循环结束时,该变量被破坏,你的指针变成了悬空,
在下一次迭代中,您创建另一个变量并在“内存中的相同位置”执行相同操作
最后,你的所有指针实际上都指向一个被破坏的对象并被称为dagling,但它们指的是一个位置,这个位置具有你最后保存的点的值。
此代码应该有效:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
int x;
int y;
};
typedef Point ppt;
int main()
{
//read input
int n;
cin >> n;
vector<ppt> v;
for(int i = 0; i < n; i ++){
Point p;
cin >> p.x;
cin >> p.y;
v.push_back(p);
}
for(int i = 0; i < n; i ++){
cout << v[i].x << " " << v[i].y << endl;
}
return 0;
}