1

我有两个课程,Curve 和 ChildCurve。ChildCurve 继承自 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

我很确定除了我在这里描述的内容之外,没有任何东西触及那个向量。有什么问题?这些值可能在哪里被破坏?

4

5 回答 5

8

这是罪魁祸首:

Point2 q1 = Point2(1.0, 3.0); 
Point2 q2 = Point2(2.0, 4.0); 
pts->push_back(&q1); 
pts->push_back(&q2);

您将指向函数本地对象的指针推送到在函数结束后仍然存在的向量中。当函数运行时,locals 是有效的,所以你可以打印出来。但是,一旦功能结束,本地人就会变得无效。试图以未定义的行为取消引用指向它们的指针。

您可以简单地通过推new Point2入向量来解决此问题,如下所示:

pts->push_back(new Point2(1.0, 3.0)); 
pts->push_back(new Point2(2.0, 4.0));

当然,您也必须删除这些对象。

更好的方法是使用 s 的向量Point2,而不是Point2*s。如果您必须为多态行为使用指针,请使用std::unique_ptr原始指针代替原始指针来简化内存管理。

于 2013-11-06T14:10:14.993 回答
1

您使用本地存储(q1q2)存储了指向对象的指针。

当您的方法结束时,这些对象不再存在并且指向它们的指针变得无效。

永远不要那样做。

于 2013-11-06T14:11:09.190 回答
1
Point2 q1 = Point2(1.0, 3.0); 
Point2 q2 = Point2(2.0, 4.0); 
pts->push_back(&q1); 
pts->push_back(&q2);

您正在存储指向堆栈变量的指针,该指针在范围结束时被销毁。这意味着当您再次访问它们时,您会调用未定义的行为。

于 2013-11-06T14:11:12.067 回答
1

请避免指针:

您作为指针传递的点 q1 和 q2 超出范围并成为垃圾。

于 2013-11-06T14:11:24.233 回答
1

q1 和 q2 是局部变量,在方法返回后被销毁。所以指向它们的指针稍后指向垃圾。

于 2013-11-06T14:15:03.010 回答