免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: mabuc
打印 上一主题 下一主题

队列为了退出,强行把自已清空,是不是多余的设计? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-05-08 10:59 |只看该作者

回复 #10 mabuc 的帖子

是啊,我只是说队列释放存在于程序中位置的问题 可能必须在析构中添加一个释放的过程

论坛徽章:
0
12 [报告]
发表于 2009-05-08 11:07 |只看该作者

回复 #5 mabuc 的帖子

C++中,如果调用delete释放内存,那么如果该指针指向一个类对象,会自动调用该类的析构函数.
free则不会.

论坛徽章:
0
13 [报告]
发表于 2009-05-08 11:26 |只看该作者
原帖由 daybreakcx 于 2009-5-8 10:56 发表
有的时候如果队列在程序已经完成任务的时候还非空呢,比如广度优先搜索找到一个解就退出,那时候可能已经退出搜索了,这时候队列可以由析构函数来进行释放吧

这时队列是可以释放,但是不能释放队列里的动态元素,队列里元素的释放不应该由队列这个容器来负责。
比如我队列容器里的元素是一系列指针,队列并不知道这些指针指向的对象在队列释放后会不会被其他模块用到。如果在队列里贸然释放了,以后其他地方引用这些对象的时候就出现非法指针。

[ 本帖最后由 gz80 于 2009-5-8 11:27 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2009-05-08 11:28 |只看该作者

回复 #13 gz80 的帖子

恩,实在任务完全结束后可以直接释放

论坛徽章:
0
15 [报告]
发表于 2009-05-08 11:56 |只看该作者

回复 #14 daybreakcx 的帖子

问题是你不能保证队列的作用域与任务的生命周期一致,而且还会有很多的限制:
(1)容器里的元素不能是对象类型,必须是指针类型,否则容器析构时无论是delete还是free都会出错;
(2)即使你的元素是指针,超出队列容器作用域后就不能引用。
(3)即使在队列容器作用域内,你申请的对象内存在放入队列后,你不能私自释放,否则会产生double free
。。。
用这样的容器真痛苦

论坛徽章:
0
16 [报告]
发表于 2009-05-08 12:14 |只看该作者

回复 #15 gz80 的帖子

(1)容器里的元素不能是对象类型,必须是指针类型,否则容器析构时无论是delete还是free都会出错;
(2)即使你的元素是指针,超出队列容器作用域后就不能引用。
(3)即使在队列容器作用域内,你申请的对象内存在放入队列后,你不能私自释放,否则会产生double free
------------------------------------
你扯太远了,
第二条,你把元素放进队列容器之后,当然要通过队列容器来引用呀,要不然放到容器中来干什么?
第三条,把元素从容器中取出来,元素和容器就没关系了,不会double free

论坛徽章:
0
17 [报告]
发表于 2009-05-08 13:22 |只看该作者

回复 #16 mabuc 的帖子

第二三点,我指对于这种情况:

如果容器Queue<class T>在析构时同时也把内在的元素析构的话:
foo(classA* pa)
{
  Queue<classA*> q;
  q.enqueue(pa);
}

main()
{
  classA* a = new classA;
  foo(a);
  a->x; //非法内存
  delete a; //double free
}

很明显,违反我们使用规范,一个好端端的对象进去一个容器兜一圈出来后就消失了。

[ 本帖最后由 gz80 于 2009-5-8 13:23 编辑 ]

论坛徽章:
0
18 [报告]
发表于 2009-05-08 14:07 |只看该作者
很好的设计, 做软件就是要做这样的完美主义者

论坛徽章:
0
19 [报告]
发表于 2009-05-08 15:39 |只看该作者
原帖由 gz80 于 2009-5-8 13:22 发表
第二三点,我指对于这种情况:

如果容器Queue在析构时同时也把内在的元素析构的话:
foo(classA* pa)
{
  Queue q;
  q.enqueue(pa);
}

main()
{
  classA* a = new classA;
  foo(a);
  a->x;  ...


你这种情况,应该clone一个,传进去。

foo(classA* pa)
{
  Queue<classA*> q;
  q.enqueue(pa);
}

main()
{
  classA* a = new classA;
  classA *b=new classA(a);
  foo(b);
  a->x; //这样就没事了
  delete a;
}

论坛徽章:
0
20 [报告]
发表于 2009-05-08 16:02 |只看该作者
原帖由 mabuc 于 2009-5-8 15:39 发表


你这种情况,应该clone一个,传进去。

foo(classA* pa)
{
  Queue q;
  q.enqueue(pa);
}

main()
{
  classA* a = new classA;
  classA *b=new classA(a);
  foo(b);
  a->x; //这样就没事 ...


所以说使用这种容器要注意很多隐性的潜规则,万一漏了哪一点都很难debug,使用者会非常痛苦。
我就没见过stl里面的哪个容器会这样做。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP