【发布时间】:2016-10-12 17:10:47
【问题描述】:
我正在玩分层对象和指针,并编写了一个基类 Circle,然后是两个类 Cylinder 和 Sphere,它们都派生自 Circle。 当我运行程序时出现错误:双重释放或损坏(输出):0x00007fffffffddf0 ***
所以我尝试通过 GDB 运行代码。我发现当我调用Cylinder析构函数时发生错误,它调用Circle的虚拟析构函数。但是我不明白为什么会这样。 根据我的研究,当代码尝试释放不可用的内存时,似乎会发生这种错误。
我认为可能是 Cylinder 的析构函数导致了问题,因为它首先被调用,所以我在 main() 中注释掉了所有 Sphere 和 Circle 对象行,只使用了 Cylinder 代码。 当调用 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;
}
【问题讨论】:
-
Ehhrm,你为什么使用
delete而你从未使用过new?我强烈建议您阅读dynamic memory management。 -
另外,将
Cylinder从Circle派生出来没有意义,因为圆柱体不是 一种(特殊的)圆圈。你做错了(TM)。你应该得到一本不错的面向对象编程的书,并阅读isa关系。