碰到一个内存释放的问题,望高手看看..搞不定啊~~~~谢谢
碰到一个内存释放的问题,望高手看看..搞不定啊~~~~
源代码如下:
#include <iostream.h>
#include <vector>
using namespace std;
class T1
{
public:
int x,y;
};
class Test
{
public:
int x,y;
T1* iptr;
Test():x(1),y(1)
{
iptr=0;
}
~Test()
{
if(iptr)
delete iptr; ///这里老是出错..
}
};
vector <Test> vc;
void test()
{
Test tt;
tt.iptr=new T1;
vc.push_back(tt);
}
void main()
{
test();
}
[解决办法]
Test必须定义拷贝构造函数,完成指针成员的深度拷贝。
vc.push_back(tt);
的时候,会将tt赋值给vc里面的元素,这样一来,tt.iptr指向 new T1生成的对象,vc[0].iptr也指向同一个对象,在函数test()的结束位置,tt离开有效期,会调用tt的析构函数,tt.iptr指向的对象会被delete一次。
当程序中,vc的有效期结束的时候,vc的析构函数,会为vc中每个元素调用析构函数,这样,vc[0].iptr指向的对象又会被delete一次。
两次delete同一对象,肯定会出错
[解决办法]
new 了1次, 但是会有2次delete iptr.所以出错。
Test()函数结束时,tt对象析构, 会有delete iptr.
vc.push_back(tt)会产生一新对象, 新对象里,iptr的值会被浅复制,导致iptr不为0.
vc对象析构时又会有delete iptr.释放了已经释放的内存,才出错。
一种是为T1增加引用计数.
一种修改是将T1* iptr改成 T1 obj;
去掉指针.
只样也不用考虑指针的引用计数.
[解决办法]
同一个对象被释放两次
~Test()
{
if(!iptr)//这里用非0
{
delete iptr; ///这里老是出错..
iptr=0;
}
}
会更安全
[解决办法]
就是浅拷贝和深拷贝的问题
一个对象占有堆等资源的时候,如果不自定义拷贝构造函数,只会进行简单的复制,不会分配新的堆等资源,就会造成两个对象指向同一个堆等资源,最后对一个一个资源释放两次而错误。
自定义拷贝构造函数时为新对象分配一个堆资源即可。