我有两个课程,Curve和ChildCurve。 ChildCurve继承自Curve。
Curve具有以下私有字段
vector<Point2*>* curvePoints;
以及以下公共方法
vector<Point2*>* getCurvePoints();
ChildCurve有一个修改此字段的方法如下。
vector<Point2*> *pts = this->getCurvePoints();
pts->clear();
Point2 q1 = Point2(1.0, 3.0);
Point2 q2 = Point2(2.0, 4.0);
pts->push_back(&q1);
pts->push_back(&q2);
cout << qvec->at(0)->getX() << ", " << qvec->at(0)->getY() << endl;
此时,将打印正确的值。
稍后,从其他一些类中,我尝试检索存储在向量中的点。
vector<Point2*> *curvePoints = curve->getCurvePoints();
for(int i = 0; i < curvePoints->size(); i++){
Point2* p = curvePoints->at(i);
cout << p->getX() << ", " << p->getY() << endl;
}
但所有点的垃圾坐标都接近0,如
2.22507e-308, 6.91993e-310
我很确定除了我在这里描述的内容之外,没有任何东西可以触及那个向量。可能有什么不对?这些价值在哪里可能会被破坏?
答案 0 :(得分:7)
这是罪魁祸首:
Point2 q1 = Point2(1.0, 3.0);
Point2 q2 = Point2(2.0, 4.0);
pts->push_back(&q1);
pts->push_back(&q2);
将指向函数本地对象的指针推送到经过函数末尾的向量。当函数运行时,本地有效,因此您可以打印它们。但是,一旦功能结束,本地人就会变得无效。试图在未定义的行为中取消引用它们的指针。
您只需将new Point2
推入向量即可解决此问题,如下所示:
pts->push_back(new Point2(1.0, 3.0));
pts->push_back(new Point2(2.0, 4.0));
当然你也必须删除这些对象。
更好的方法是使用Point2
s的向量,而不是Point2*
s。如果必须使用指针来表示多态行为,请使用std::unique_ptr
而不是原始指针来简化内存管理。
答案 1 :(得分:1)
您存储了指向具有本地存储(q1
和q2
)的对象的指针。
当您的方法结束时,这些对象将不复存在,并且指向它们的指针将变为无效。
永远不要那样做。
答案 2 :(得分:1)
Point2 q1 = Point2(1.0, 3.0);
Point2 q2 = Point2(2.0, 4.0);
pts->push_back(&q1);
pts->push_back(&q2);
您正在存储指向堆栈变量的指针,这些指针会在范围结束时被销毁。再次访问它们时的含义,您将调用未定义的行为。
答案 3 :(得分:1)
请避免指点:
你的点q1和q2作为指针超出范围而变成垃圾。
答案 4 :(得分:1)
q1和q2是局部变量,在方法返回后被销毁。所以指向它们的指针稍后指向垃圾。