C++-为什么这段程序会崩溃?
这段程序除了内存泄漏以外,还有崩溃的问题,为什么?
#include <iostream>
class Shape
{
public:
virtual void draw() const = 0;
};
class Circle : public Shape
{
public:
virtual void draw() const { }
int radius;
};
class Rectangle : public Shape
{
public:
virtual void draw() const { }
int height;
int width;
};
int main()
{
Shape * shapes = new Rectangle[10];
for (int i = 0; i < 10; ++i)
shapes[i].draw();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
shapes指向的是数组Rectangle的起始地址,这是对的,但shapes是shape指针,shapes[i]是shape指针类型进行偏移增加。
假如:Shape * shapes = new Rectangle[10];后shapes指向的是地址0.
sizeof(Rectangle)=12,sizeof(Shape)=4,new操作后申请的空间是sizeof(Rectangle)*10=120;
shapes[0]指向地址0,这个对了,但shapes[1]指向了地址4(即第一个Rectangle的变量height的地址),shapes[2]指向地址8(即第一个Rectangle的变量width的地址),shapes[3]指向地址12(即第二个Rectangle地址)依次类推。
也就是说shapes[i]是以Shape指针类型进行移位的,而不是你想象的Rectangle指针类型。这下知道为什么崩溃了吧。shapes[1]指向的根本不是你要的Rectangle对象。
`Shape * shapes = new Rectangle[10];`//这里是不对的,应该采用如下写法:
Shape** shapes = new Shape*[10];
for(uint32 i=0; i<10; ++i)
shapes[i] = new Rectangle;
崩溃的原因在于遍历过程中,shapes[i]实际上是shapes+1,你期待的是得到一个指向下一个Rectangle的指针,可是,shapes的类型是指向Shape的指针,在做shapes+1操作的时候实际上指针偏移的地址大小为一个Shape占据的空间而不是一个Rectangle占据的空间,也就是说指针偏移之后,指针将下一片不是Rectangle的存储解释为Rectangle,这样出错是理所当然的。