2016-10-12 2 views
0

나는 계층 적 객체와 포인터를 가지고 놀고 있으며 Circle에서 파생 된 두 클래스 인 Cylinder와 Sphere 두 클래스를 작성했다. 프로그램을 실행할 때 double free 또는 corruption (out)이 발생했습니다. 0x00007fffffffddf0 ***Error : double free or corruption (out) : 0x00007fffffffddf0 ***

그래서 GDB를 통해 코드를 실행 해 보았습니다. Circle의 가상 소멸자를 호출하는 Cylinder 소멸자를 호출 할 때 오류가 발생하는 것으로 나타났습니다. 그러나 나는 이것이 왜 일어나고 있는지 이해하지 못한다. 제 연구에서 코드가 사용할 수없는 메모리를 할당 해제하려고 시도 할 때 이런 종류의 오류가 발생하는 것으로 보입니다.

나는 Cylinder의 소멸자가 먼저 호출 되었기 때문에이 문제를 일으키는 것으로 생각했기 때문에 main()의 Sphere와 Circle 객체 라인을 모두 주석 처리하고 Cylinder 코드를 사용했다. 실린더 포인터의 소멸자가 호출되면 세그먼트 화 오류가 발생하여 범위를 벗어난 메모리에 액세스하려고합니다.

이제 완전히 혼란 스럽습니다. 다음 그들에 대한 포인터에 삭제 호출,

#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

실린더가 원 (특별한 종류의 원)이 아니기 때문에'Circle'에서 파생 된'Cylinder'에 대해서는 * 아무 의미가 없습니다. 당신은 잘못하고 있습니다 (TM). 당신은 객체 지향 프로그래밍에 관한 적당한 책을 얻어야하고'isa' 관계에 대해 읽어야합니다. –

답변

2

당신은 스택에 실린더와 영역을 할당하고 있습니다 :

여기 내 코드입니다. 이것은 당신의 물건을 두 번 파괴 할 것입니다. 한 번 삭제할 때 전화하고 한 번 범위 (주 끝)를 벗어날 때.

new를 사용하여 생성하지 않은 개체에 대해서는 delete를 호출하지 마십시오. 특히 스택 객체의 주소에서 delete를 호출하지 마십시오.

관련 문제