迅雷一道C++面试题!!!求解释
#include <iostream>
using namespace std;
class Base
{
public:
void fun()
{
cout << "Base::fun()" << endl;
}
};
class Derived : public Base
{
public:
virtual void fun()
{
cout << "Derived::fun()" << endl;
}
};
int main()
{
Base *p=new Derived;
p->fun();
delete p;
p=NULL;
return 0;
}
请问各位C++大侠,为什么执行到delete p的时候,运行时崩溃了!!能从对象内存布局角度来解释吗?(个人只知道在执行父类析构函数的时候发生崩溃)
[解决办法]
嗯,3q,有点明白了。但是我搞不懂的一点是,即使是内存泄露,怎么会造成运行时崩溃呢?
派生类有虚函数,使用了动态联编,会在类里面多出一个vptr指针来指向虚函数表,以及多出来的一张虚函数表。delete p只是调用基类的析构函数,很明显没有释放派生类里面多出来的内容,造成内存泄露。 这边你可以声明一个虚拟的析构函数,也可以将基类中的fun函数也声明为虚拟的,这样的话,基类中就会也有vptr,和虚函数表,派生类只是继承这些内容。因此在基类的析构就足以将需要释放的资源释放了
这边会崩溃是因为以基类指针来存储来存储派生类的地址和用存储派生类地址,值是不一样的,你上面这篇文章说的是错的http://blog.csdn.net/unituniverse2/article/details/12302139,不信你可以打印出来看看,
Derived *sp=new Derived;
Base *p=sp;
这边差4,恰好是一个指针的大小。
崩溃的原因是因为detlete p;将调用 全局的void operator delete( void * addr, size_t size),这边穿进去的是基类部分的指针,在函数里面要free(addr),但是我们new 的时候调用的malloc()并不是new出的addr这块内存,而是sp指向派生类的地址,free和malloc不匹配当然会崩溃。http://www.wuzesheng.com/?p=840这边看看就懂了