指针对象在某处被破坏

时间:2013-11-06 14:07:38

标签: c++ pointers vector

我有两个课程,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

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

5 个答案:

答案 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)

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

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

永远不要那样做。

答案 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是局部变量,在方法返回后被销毁。所以指向它们的指针稍后指向垃圾。