错误:双重免费或损坏(退出):0x00007fffffffddf0 ***

时间:2016-10-12 17:10:47

标签: c++ pointers object gdb

我正在玩分层对象和指针,并编写了一个基类Circle,然后是两个类Cylinder和Sphere,它们都来自Circle。 当我运行程序时,我收到错误:double free或corruption(out):0x00007fffffffddf0 ***

所以我尝试通过GDB运行代码。我发现当我调用Cylinder析构函数时会发生错误,该析构函数调用Circle的虚析构函数。但是,我不明白为什么会这样。 根据我的研究,当代码试图释放不可用的内存时,似乎会发生这种错误。

我想也许Cylinder的析构函数引起了问题,因为它首先被调用,所以我在main()中注释掉了所有的Sphere和Circle对象行,并且只使用了Cylinder代码。 当调用Cylinder指针的析构函数时,它导致了Segmentation Fault,所以我试图访问超出范围的内存。

现在我完全糊涂了。

这是我的代码:

#include <iostream>
#include <cmath>    // used for square
static constexpr float PI = 3.14159;

using namespace std;

class Circle{
protected:
    float radius;
public:
    float getRadius(){
        return radius;
    }
    void setRadius(float r){
        radius = r;
    }
    float calcCircleArea(){
        return PI * pow(radius, 2);
    }
    float calcCircumference(){
        return 2 * PI * radius;
    }
    Circle(){
        // default constructor
    }
    Circle(float rad){
        radius = rad;   // overloaded constructor 
    }
    virtual ~Circle(){  // virtual destructor
        cout << "Destroying Circle Constructor" << endl;
    }
};

class Cylinder: public Circle{
private:
    float height;
public:
    float getHeight(){
        return height;
    }
    void setHeight(float h){
        height = h;
    }
    float calcVol(){
        float circleArea = calcCircleArea();
        float vol = circleArea * height;
    }
    float calcSurfaceArea(){
        float circum = calcCircumference();
        float circleArea = calcCircleArea();
        float cylSurfArea = (circleArea *2) + (circum * height);
    }
    Cylinder(){}    // default constructor

    Cylinder(float r, float h){ // overloaded constructor
        radius = r;
        height = h;
    }
    ~Cylinder(){    // destructor
        cout << "Destroying Cylinder Constructor" <<endl; 
    }
};

class Sphere : public Circle {
public:
    float calcSurfaceArea(){
        float r = getRadius();
        return 4* PI * pow(r,2);
    }
    float calcVol(){
        float r = getRadius();
        return (4.0/3.0) * PI * pow(r,3);
    }
    Sphere(){}  // default constructor

    Sphere(float r){
        radius = r;
    }
    ~Sphere(){  // destructor
        cout << "Destroying Sphere Constructor" << endl;
    }
};

int main(){
    cout << "Enter radius of circle and height of cyl:" << endl;
    float r;
    float h;
    cin >> r >> h;
    Sphere s1(r);
    Cylinder cyl1(r,h);
    Circle cir1(r);

 //****************************
 //     Set up pointers
 //****************************
    Circle *circPtr;
    circPtr = &cir1;
    Sphere *sPtr;
    sPtr = &s1;
    Cylinder *cylPtr;
    cylPtr = &cyl1;

    cout << "Sphere vol : " << sPtr->calcVol() << endl;
    cout << "Sphere SA : " << sPtr->calcSurfaceArea() << endl;

    cout << "Cyl vol : " << cylPtr->calcVol() << endl;
    cout << "Cyl SA : " << cylPtr->calcSurfaceArea() << endl;

    cout << "Circle area : " << circPtr->calcCircleArea() << endl;
    cout << "Circle circum : " << circPtr->calcCircumference() << endl;

    cout << "sphere RADIUS : " << sPtr->getRadius() << endl;
    cout << "cyl pointer VOLUME : " << cylPtr->calcVol() << endl;
    cout << "circ pointer AREA: " << circPtr->calcCircleArea() << endl;

    delete cylPtr;
    delete sPtr;

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您在堆栈上分配柱面和球体,然后在指向它们的指针上调用delete。这会两次破坏你的对象。一旦你打电话给删除,一旦他们超出范围(主要目的)。

请勿在您未使用新功能创建的对象上调用delete。特别是不要在堆栈对象的地址上调用delete。