2016-10-12 50 views
0

我正在玩分層對象和指針,並寫了一個基類圓,然後兩個類圓柱體和球體都來自圓。 當我運行程序時,出現錯誤:double free或corruption(out):0x00007fffffffddf0 ***錯誤:雙重空閒或腐敗(出):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; 
} 
+4

Ehhrm,你爲什麼在你從未使用'new'的地方使用'delete'?我會認真地推薦你閱讀[動態內存管理](http://en.cppreference.com/w/cpp/memory)。 –

+0

另外,由於圓柱體不是*(圓形)的特殊圓形,所以'Cylinder'從'Circle'派生出來會使*無意義*。你做錯了(TM)。你應該得到一本關於面向對象編程的好書,並閱讀關於「isa」關係的書。 –

回答

2

你在棧上分配好自己的圓柱體和球體,然後調用刪除指向他們。這會摧毀你的對象兩次。一旦你打電話給刪除,以及一旦他們超出範圍(主要目的)。

不要對沒有用新建的對象進行調用刪除。特別是不要在堆棧對象的地址上調用delete。

相關問題