我正在玩分层对象和指针,并编写了一个基类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;
}
答案 0 :(得分:2)
您在堆栈上分配柱面和球体,然后在指向它们的指针上调用delete。这会两次破坏你的对象。一旦你打电话给删除,一旦他们超出范围(主要目的)。
请勿在您未使用新功能创建的对象上调用delete。特别是不要在堆栈对象的地址上调用delete。