问一个关于STL的问题

enterlc 2003-11-20 08:36:56
在STL中

class A
{
public:
A(){cout<<"constrcut A"<<endl;}
virtual ~A(){cout<<"destrcut A"<<endl;}

};

class B
{
public:
B(){cout<<"constrcut B"<<endl;}
virtual ~B(){cout<<"destrcut B"<<endl;}

list<A*> la;
};

main()
{
B* b = new B;
for(int i=0;i<10;i++)
{
A* a=new A;
b->la.push_back(a);
}
delete b; //在这里,会不会把push到la中的A*指针全部delete,是否 会产生内存泄漏?
//如果不是,是否需要在B的析构函数中来调用la.clear() 或者

//la.erase(la.begin(),la.end())
//不过我这样试了一下,好想还是不会去调~A()
//请问这种情况应该如何处理?
}
...全文
75 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinliu 2003-11-27
  • 打赏
  • 举报
回复
在Container中放的你new的对象指针,在Container销毁前,你必须首先销毁指针对象,否则泄漏。Container在销毁前,会对每个对象进行析构,但指针这种对象类型的析构是什么也不作,好象int对象类型一样!
mfcer2 2003-11-27
  • 打赏
  • 举报
回复
mark
jinliu 2003-11-27
  • 打赏
  • 举报
回复
用智能指针,不用自己写,STLPORT和Loki都给你写好了
begginginstorm 2003-11-27
  • 打赏
  • 举报
回复
用指针确实效率很高,尤其是处理大对象的时候。但是,不容忽视,用指针很容易犯错误:所以嘛,我们要用智能指针。standard C++或者STL中container、algorithm、functor、iterator等都不错,就是auto_ptr不太争气。据说,C++标准制定的时候,对于auto_ptr有很多不同的意见,最后大家相持不下,最后导致auto_ptr并没有人们预想中的那么好。

不过事实上,不同的情况都会有不同需求的指针,比如转移控制权的、计数的、全局的等等,自己写一个个性化需求的智能指针并非难事,所以另外一个选择就是使用智能指针。
xianjing 2003-11-25
  • 打赏
  • 举报
回复
对了,对于上述的情况,我一般都是在析构函数里面释放内存!
xianjing 2003-11-25
  • 打赏
  • 举报
回复
但是放指针的效率很高,我还是经常放的,不过释放和安全问题当然要自己搞定了,呵呵!
cxjddd 2003-11-25
  • 打赏
  • 举报
回复
在容器里放指针是很危险的啊:)
小心:)
enterlc 2003-11-23
  • 打赏
  • 举报
回复
有人知道吗?
xiaolizi 2003-11-23
  • 打赏
  • 举报
回复
补充:这样看来,好像容器中放指针是个麻烦的操作,何不干脆放变量的实体?这是因为从效率上考虑,这边假设有一个很复杂的类class A,在对容器进行加入操作的时候如list.push_back( A& var ) 这样的操作,list在插入的时候执行的是: node_var = var;,node_var是list内部的一个变量。这边的赋值语句“=”对于复杂类来讲开销很大,而如果是一个A* ptr的话,仅仅是一个指针赋值。另外如果是vector容器且不固定大小,强烈建议用指针作为存储变量,因为vector的push_back操作可能包含着大量的数据迁移,而类的创建和销毁是很花资源的。
xiaolizi 2003-11-23
  • 打赏
  • 举报
回复
list,vector等容器中的元素,容器本身是不会自动调用delete的。
比如list< int >和 list< int* >, list< int* >中的元素如果用户不主动遍历链表做删除操作是要有内存泄漏的。所以list中的clear只是仅仅负责把链表清空,而不做delete操作。
对于存放在容器中的是指针变量,每一个容器在销毁前需要做内存释放的动作:
list< int* >::iterator it = _list_var.begin();
for( ; it != _list_var.end(); ++it ) {
delete( (*it) );
}
enterlc 2003-11-21
  • 打赏
  • 举报
回复
我本来也是这么想的,但这样list析构的时候会去析构里面所有的A*吗?
enterlc 2003-11-21
  • 打赏
  • 举报
回复
那这种情况下应该怎么处理呢?

另外在STL中,好像是先调operator new ,再调placement new
结束的时候先是~T(),然后是operator delete

Test * p = new Test;这个p是谁来delete?
Wolf0403 2003-11-21
  • 打赏
  • 举报
回复
这样会造成内存泄露。示例代码如下:
class Test
{
public:
void * operator new (size_t _size)
{
cout << "New" << endl;
return ::operator new (_size);
}
void operator delete (void * p)
{
cout << "Delete" << endl;
return ::operator delete (p);
}
};

int main(void)
{
list<Test *> l;
for (int i = 0; i < 20; i++)
{
Test * p = new Test;
l.push_back(p);
}
}
会看到只调用了 20 个 operator new 而没有调用 operator delete
测试环境 vc 7.1
Andy84920 2003-11-20
  • 打赏
  • 举报
回复
delete b; //在这里,会不会把push到la中的A*指针全部delete,是否 会产生内存泄漏?
============================================================
不会.
不会产生内存泄漏.因为list它自己会管理它内部对象的内存问题.(分配与释放).
你的类B也析构函数中根本没有这个考虑.
还有你把它们的析构函数定义成virtual,需要吗?它们不存在继承关系啊!
---------------------------------------------------------------------
//如果不是,是否需要在B的析构函数中来调用la.clear() 或者

//la.erase(la.begin(),la.end())
----------------------------

不用!你自己没有分配什么,不用管,让STL的list去帮你管!
---------------------
//不过我这样试了一下,好想还是不会去调~A()
//请问这种情况应该如何处理?
}

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧