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

关于 初始化列表 失败

ericyosho
2008/7/3镜像同步4 回复
看TIC++,卷2,那个猫和狗的例子。 class UseResources { Cat *bp; Dog *op; public: UseResources (int sz=3) { *bp = new Cat[sz]; *op = new Dog; } }; 他的意思是,当红色语句由于内存不足丢出异常以后,Dog的内存申请没有成功,Cat的那个数组申请成功,但是由于抛出异常,析构函数没有执行,无法释放,造成内存泄漏。 提供的解决方案是把那两个指针包裹在两个模板类中。调用的示意如下: class UseResources { PWrap<Cat, 3> C; PWrap<Dog, 1> D; public: UseResources: C(), D() {}; }; 要说区别,就是把对内存的申请,由构造函数内移入了初始化列表。 我的问题是,初始化列表这个过程是原子性的么?如果初始化列表失败了,就会释放Cat的那个数组么?没有想明白。
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
UnitTest机器人#1 · 2008/7/4
【 在 ericyosho 的大作中提到: 】 : 要说区别,就是把对内存的申请,由构造函数内移入了初始化列表。 : ................... 不对,区别在于把对内存的申请放入了另外一个对象里面,其实就是资源管理思想(RAII)的运用。在这个例子里面,你写不写初始化列表效果是一样的,它都照样会调用C和D的默认构造函数。关键是异常的问题,当抛出异常的时候,如果你在外面某一级把这个异常try catch住了,它会正常析构掉已经正确构造的局部对象,也就是在D被构造之前,C已经被正常构造了的话,抛出异常的时候C会被正常地析构。 至于异常实现的机制,我也并不是很清楚,就大概知道,如果你使用了try catch的话,编译器会自动插入一些处理的代码,实际上它使用的是操作系统提供的结构化异常(SEH)来完成的,Java/.net的异常实现也都是用SEH来完成的。然后抛出异常的时候,会沿着调用链反向进行栈开解(Stack Unwind),析构掉已经成功构造的局部对象,直至遇上合适的try catch 至于一些具体的异常细节问题尤其是SEH,那可要请教茫猪这些研究底层的大牛了~~
ericyosho机器人#2 · 2008/7/4
楼上说的这个,是集中在,如果有合适的 catch 子句被执行时。 那我们能不能这样想,如果在前面的那种裸指针的时候,如果用好 try catch ,并写好合理的处理语句,我们同样可以保证没有内存的泄漏呢? 还有,如果没有合适的 catch 子句被执行呢?又会有啥情况?
UnitTest机器人#3 · 2008/7/4
【 在 ericyosho 的大作中提到: 】 : 楼上说的这个,是集中在,如果有合适的 catch 子句被执行时。 : 那我们能不能这样想,如果在前面的那种裸指针的时候,如果用好 try catch ,并写好合理的处理语句,我们同样可以保证没有内存的泄漏呢? : 还有,如果没有合适的 catch 子句被执行呢?又会有啥情况? 在baidu搜到这个 http://zyliusunny.bokee.com/viewdiary.13335374.html 在effective系列应该会讲有这些问题,你可以去翻翻
ericyosho机器人#4 · 2008/7/5
好, see see 这个。