2016-10-12 2 views
0

Я играю с иерархическими объектами и указателями и написал базовый класс Circle, затем два класса Cylinder и Sphere, которые оба происходят от Circle. Когда я запускаю программу, я получаю ошибку: double free или коррупция (out): 0x00007fffffffddf0 ***Ошибка: двойная свобода или коррупция (out): 0x00007fffffffddf0 ***

Итак, я попытался запустить код через GDB. Я обнаружил, что ошибка возникает, когда я вызываю деструктор Cylinder, который вызывает виртуальный деструктор для Circle. Однако я не понимаю, почему это происходит. Из моего исследования, похоже, такая ошибка возникает, когда код пытается освободить память, которая недоступна для него.

Я думал, что деструктор для Цилиндра вызывал проблему, так как он называется первым, поэтому я прокомментировал все линии объекта Sphere и Circle в main() и просто использовал код цилиндра. Когда деструктор указателя Цилиндра был вызван, он привел к ошибке сегментации, поэтому я пытаюсь получить доступ к памяти за пределами диапазона.

Теперь я полностью смущен.

Вот мой код:

#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

Эх, почему вы используете 'delete', где вы никогда не использовали' new' ?? Я серьезно рекомендую вам ознакомиться с [динамическим управлением памятью] (http://en.cppreference.com/w/cpp/memory). –

+0

Также он делает * no sense * для 'Cylinder', который должен быть получен из' Circle', потому что цилиндр - это * не * a (особый вид) круга. Вы делаете это неправильно (TM). Вы должны получить приличную книгу по объектно-ориентированному программированию и прочитать о отношениях 'isa'. –

ответ

2

Вы выделение своего цилиндра и сферы в стеке, то вызов удаления на указатели на них. Это уничтожит ваши объекты дважды. Однажды, когда вы вызываете delete, и один раз, когда они выходят из области действия (основные концы).

Не вызывайте удаление объектов, которые вы не создали с новыми. Особенно не вызывайте delete по адресу объектов стека.

Смежные вопросы