BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #47730同步于 2010/12/13
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

关于虚析构函数的用法的疑问

jiangj
2010/12/13镜像同步16 回复
c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。 现在的疑问是: 如果基类的析构函数不是虚函数,代码例子: Base是基类,Derived是派生类, Base *p = new Derived; delete p; 那我如果将指向基类Base的指针删除了后,确实是只调用了Base基类的析构函数,而没有调用Derived的析构函数,那么子类Derived部分会怎么样?占用的内存空间会自动释放还是会造成内存泄露? 我做了一个while(1)循环,没有发现内存增长,那子类暂用的空间应该是自动释放了,那是在什么时候释放的?
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
wildpointer机器人#1 · 2010/12/13
【 在 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)循环,没有发现内存增长,那子类暂用的空间应该是自动释放了,那是在什么时候释放的?
jiangnanbuyi机器人#2 · 2010/12/13
应该会有内存泄漏的,不知楼主是如何确定内存没有增长的
jiangj机器人#3 · 2010/12/13
看任务管理器进程的内存使用有没有增加 【 在 jiangnanbuyi 的大作中提到: 】 : 应该会有内存泄漏的,不知楼主是如何确定内存没有增长的
jiangj机器人#4 · 2010/12/13
恩,按你这样写确实会挂掉----- 但如果你将 virtual ~Derived() 改成 ~Derived() 就不会挂了... 求大牛解释下为什么会这样啊-_- 【 在 wildpointer 的大作中提到: 】 : 这样,会出现什么情况就很难讲了。 : 下面的程序,在我的机器上运行,直接就退出了。 : #include <iostream> : ...................
shenlei机器人#5 · 2010/12/13
【 在 jiangnanbuyi 的大作中提到: 】 : 应该会有内存泄漏的,不知楼主是如何确定内存没有增长的 : -- 在vs2010下,用_CrtDumpMemoryLeaks();看了下,确实没有内存泄漏...
a206206机器人#6 · 2010/12/13
默认的析构函数不就是什么都不做么,大多数析构函数中有用的部分都是delete吧,我觉得占用内存释放(整个类的,除了new)是由操作系统管理的,个人见解,请大牛指点
landiya机器人#7 · 2010/12/14
子类里面没创建内存吧 【 在 jiangj 的大作中提到: 】 : c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。 : 现在的疑问是: : 如果基类的析构函数不是虚函数,代码例子: : ...................
jiangj机器人#8 · 2010/12/14
如果子类没有占用内存,那么实现多态的时候,子类的数据放在什么地方? 【 在 landiya 的大作中提到: 】 : 子类里面没创建内存吧 : 【 在 jiangj 的大作中提到: 】 : : c++ primer 上说析构函数 声明为虚函数的话,可以保证运行适当的析构函数,基类的析构函数必须是虚函数。 : ...................
zhuifengliuq机器人#9 · 2010/12/14
【 在 jiangj 的大作中提到: 】 : 如果子类没有占用内存,那么实现多态的时候,子类的数据放在什么地方? : 【 在 landiya 的大作中提到: 】 : : 子类里面没创建内存吧 : ................... 把代码贴出来看看嘛