返回信息流c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。
现在的疑问是:
如果基类的析构函数不是虚函数,代码例子:
Base是基类,Derived是派生类,
Base *p = new Derived;
delete p;
那我如果将指向基类Base的指针删除了后,确实是只调用了Base基类的析构函数,而没有调用Derived的析构函数,那么子类Derived部分会怎么样?占用的内存空间会自动释放还是会造成内存泄露?
我做了一个while(1)循环,没有发现内存增长,那子类暂用的空间应该是自动释放了,那是在什么时候释放的?
这是一条镜像帖。来源:北邮人论坛 / cpp / #47730同步于 2010/12/13
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
关于虚析构函数的用法的疑问
jiangj
2010/12/13镜像同步16 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 jiangj (roach) 的大作中提到: 】
: c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。
: 现在的疑问是:
: 如果基类的析构函数不是虚函数,代码例子:
: Base是基类,Derived是派生类,
: Base *p = new Derived;
: delete p;
这样,会出现什么情况就很难讲了。
下面的程序,在我的机器上运行,直接就退出了。
#include <iostream>
using namespace std;
class Base
{
public:
int i1;
Base()
{
cout << "Base::Base()" << endl;
}
};
class Derived : public Base
{
public:
double d;
virtual ~Derived()
{
cout << "Derived::~Derived()" << endl;
}
};
int main()
{
while(1)
{
Base *bp = new Derived();
delete bp;
}
return 0;
}
运行的时候出现下面的情况
Base::Base()
*** glibc detected *** ./a.out: free(): invalid pointer: 0x08da700c ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0x3030d1]
/lib/tls/i686/cmov/libc.so.6[0x3047d2]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x3078ad]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x5726f1]
./a.out[0x80488e4]
/lib/tls/i686/cmov /libc.so.6(__libc_start_main+0xe6)[0x2aeb56]
./a.out[0x80487e1]
======= Memory map: ========
00110000-00134000 r-xp 00000000 08:06 1966319 /lib/tls/i686/cmov/libm-2.1
0.1.so
00134000-00135000 r--p 00023000 08:06 1966319 /lib/tls/i686/cmov/libm-2.1
0.1.so
00135000-00136000 rw-p 00024000 08:06 1966319 /lib/tls/i686/cmov/libm-2.1
0.1.so
00136000-00152000 r-xp 00000000 08:06 2406 /lib/libgcc_s.so.1
00152000-00153000 r--p 0001b000 08:06 2406 /lib/libgcc_s.so.1
00153000-00154000 rw-p 0001c000 08:06 2406 /lib/libgcc_s.so.1
0027b000-00296000 r-xp 00000000 08:06 5014 /lib/ld-2.10.1.so
00296000-00297000 r--p 0001a000 08:06 5014 /lib/ld-2.10.1.so
00297000-00298000 rw-p 0001b000 08:06 5014 /lib/ld-2.10.1.so
00298000-003d6000 r-xp 00000000 08:06 1966522 /lib/tls/i686/cmov/libc-2.1
0.1.so
003d6000-003d7000 ---p 0013e000 08:06 1966522 /lib/tls/i686/cmov/libc-2.1
0.1.so
003d7000-003d9000 r--p 0013e000 08:06 1966522 /lib/tls/i686/cmov/libc-2.1
0.1.so
003d9000-003da000 rw-p 00140000 08:06 1966522 /lib/tls/i686/cmov/libc-2.1
0.1.so
003da000-003dd000 rw-p 00000000 00:00 0
004ba000-005a0000 r-xp 00000000 08:06 1350 /usr/lib/libstdc++.so.6.0.1
3
005a0000-005a4000 r--p 000e6000 08:06 1350 /usr/lib/libstdc++.so.6.0.1
3
005a4000-005a5000 rw-p 000ea000 08:06 1350 /usr/lib/libstdc++.so.6.0.1
3
005a5000-005ac000 rw-p 00000000 00:00 0
0060e000-0060f000 r-xp 00000000 00:00 0 [vdso]
08048000-08049000 r-xp 00000000 08:06 11272199 /home/wildpointer/code/cc/a.
out
08049000-0804a000 r--p 00000000 08:06 11272199 /home/wildpointer/code/cc/a.
out
0804a000-0804b000 rw-p 00001000 08:06 11272199 /home/wildpointer/code/cc/a.
out
08da7000-08dc8000 rw-p 00000000 00:00 0 [heap]
b7600000-b7621000 rw-p 00000000 00:00 0
b7621000-b7700000 ---p 00000000 00:00 0
b7728000-b772a000 rw-p 00000000 00:00 0
b7742000-b7745000 rw-p 00000000 00:00 0
bf91a000-bf92f000 rw-p 00000000 00:00 0 [stack]
Aborted
: 那我如果将指向基类Base的指针删除了后,确实是只调用了Base基类的析构函数,而没有调用Derived的析构函数,那么子类Derived部分会怎么样?占用的内存空间会自动释放还是会造成内存泄露?
: 我做了一个while(1)循环,没有发现内存增长,那子类暂用的空间应该是自动释放了,那是在什么时候释放的?
恩,按你这样写确实会挂掉-----
但如果你将
virtual ~Derived()
改成
~Derived()
就不会挂了...
求大牛解释下为什么会这样啊-_-
【 在 wildpointer 的大作中提到: 】
: 这样,会出现什么情况就很难讲了。
: 下面的程序,在我的机器上运行,直接就退出了。
: #include <iostream>
: ...................
【 在 jiangnanbuyi 的大作中提到: 】
: 应该会有内存泄漏的,不知楼主是如何确定内存没有增长的
: --
在vs2010下,用_CrtDumpMemoryLeaks();看了下,确实没有内存泄漏...
默认的析构函数不就是什么都不做么,大多数析构函数中有用的部分都是delete吧,我觉得占用内存释放(整个类的,除了new)是由操作系统管理的,个人见解,请大牛指点
子类里面没创建内存吧
【 在 jiangj 的大作中提到: 】
: c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。
: 现在的疑问是:
: 如果基类的析构函数不是虚函数,代码例子:
: ...................
如果子类没有占用内存,那么实现多态的时候,子类的数据放在什么地方?
【 在 landiya 的大作中提到: 】
: 子类里面没创建内存吧
: 【 在 jiangj 的大作中提到: 】
: : c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。
: ...................
【 在 jiangj 的大作中提到: 】
: 如果子类没有占用内存,那么实现多态的时候,子类的数据放在什么地方?
: 【 在 landiya 的大作中提到: 】
: : 子类里面没创建内存吧
: ...................
把代码贴出来看看嘛