Ross Satchell
Ross Satchell

Reputation: 351

Error: double free or corruption (out): 0x00007fffffffddf0 ***

I am playing around with hierarchical objects and pointers and have written a base class Circle, then two classes Cylinder and Sphere that both derive from Circle. When I run the program I get the error: double free or corruption (out): 0x00007fffffffddf0 ***

So I tried running the code through GDB. I found that the error occurs when I call the Cylinder destructor, which calls the virtual destructor for Circle. However I don't understand why this is happening. From my research it seems this kind of error occurs when the code tries to deallocate memory that is not available to it.

I thought perhaps the destructor for Cylinder was causing the problem, since it is called first, so I commented out all of the Sphere and Circle object lines in main() and just used the Cylinder code. When the destructor for the Cylinder pointer was called it resulted in a Segmentation Fault, so I am trying to access memory out of range.

Now I'm thoroughly confused.

Here is my code:

#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;
}

Upvotes: 1

Views: 3784

Answers (1)

MarcD
MarcD

Reputation: 618

You're allocating your cylinder and sphere on the stack, then calling delete on pointers to them. This will destroy your objects twice. Once when you call delete, and once when they go out of scope (main ends).

Don't call delete on objects that you didn't create with new. Especially don't call delete on the address of stack objects.

Upvotes: 3

Related Questions