我需要载入一个文件的数据,并且将数据读到内存中,在这个读取的过程中,我不断的new空间(类型是自定义的一个类),并且把首地址赋值到一个CTypedPtrArray类型的数组。这个数组比较大,动辄上万个元素。
关闭文件时,我希望释放内存,就是在另外一个函数中,把元素一个个取出来delete。
现在的情况是,debug版,能够正常的释放空间,比如在任务管理器查看程序占用的内存,打开文件前占用100M,打开后是150M,关闭文件时这个占用的内存可以降到100M左右,但是release版本却不行,可能只降到120M。但是release也不会报错,关闭时正常运行。
我检查过,delete的次数是一样的,并且检查了部分delete的空间大小(用sizeof(*p)查看)也是一样的。
我查过两个编译的版本的区别,但是找到的说的都是两者编译的时候一些参数的设置的区别,还有就是类似变量初始化的问题,也有自定义消息响应函数的问题。我试过编译的一些参数的设置没办法解决,还有变量初始化这些都没问题。 请各位支支招!!!!分数可以继续加。谢谢各位高手了。
关闭文件时,我希望释放内存,就是在另外一个函数中,把元素一个个取出来delete。
现在的情况是,debug版,能够正常的释放空间,比如在任务管理器查看程序占用的内存,打开文件前占用100M,打开后是150M,关闭文件时这个占用的内存可以降到100M左右,但是release版本却不行,可能只降到120M。但是release也不会报错,关闭时正常运行。
我检查过,delete的次数是一样的,并且检查了部分delete的空间大小(用sizeof(*p)查看)也是一样的。
我查过两个编译的版本的区别,但是找到的说的都是两者编译的时候一些参数的设置的区别,还有就是类似变量初始化的问题,也有自定义消息响应函数的问题。我试过编译的一些参数的设置没办法解决,还有变量初始化这些都没问题。 请各位支支招!!!!分数可以继续加。谢谢各位高手了。
就是在一个地方new,然后赋值
在另外一个地方不断的GetAt[i],然后delete p;
是仅仅刚结束的时候多占20M 内存还是以后一直这样?
频繁启动这个release的exe就能看出是不是吃内存,如果就保持这个水平我觉得你完全可以忽略不管它。
比如打开文件前,release占用100M,打开后150M,关闭文件后就是120M左右。
现在关键不是这里占用多少,而是这个数据差跟我打开的文件大小有关(其实就是跟new的次数有关),如果我打开的是几百兆的文件的话,这个相差就有几百兆甚至1g了。
至于指针,我是这样用的。假设存储数据的类是CData.它有自己的构造函数,分别对各个数据成员赋值。
CData* p=new CData();
p->member1=*******;//多条类似的语句赋值给部分成员,一部分成员没有赋值,赋值验证正确。
……
m_Array.Add(p);//然后把这个p存到CTypedPtrArray类型的数组m_Array.
释放的时候:for(int i=0;i<m_Array.GetSize();i++)
{
CData *p=m_Array.GetAt(i);
delet p;
}
m_Array.RemoveAll();这样的操作有什么问题么?
对于频繁分配内存的情况,最好按照逆序释放,即后分配的内存先释放,这样程序的性能会好一些。
{
CData *p=m_Array.GetAt(i);
delet p;
} 没有问题。
这个东西我一般都倒删,你这里用GetAt是没事,要是删除就出事儿了。
lz幸运啊
还是看看CData的内部吧
第一,把CData类new和delete的代码注释掉,看看内存变化如何。
第二,把CData类换成一个简单类,比如就一个整型成员变量的类,看内存变化如何。
另外,不妨把你CData类的成员变量贴出来看看,另外确定该类的成员不会有泄漏问题。包括句柄等,都已释放。
{
CData *p=m_Array.GetAt(i);
delet p;
}
m_Array.RemoveAll(); 试试在这后面加上freeextra,曾经有个项目,在VC6下面与楼主的释放代码一样,没什么问题,但在2005下报内存泄露,在这后面加上
m_Array.FreeExtra();就没事了.可以试一下.
CData的成员变量不方便给出么?
试过啦??
管它了
另外,我自己用了一个指针数组来保存指针,还是一样的效果。
可以试试分配的链表头设为最末分配的内存,这样从头删除就符合系统顺序了,
也可以一次性分配CData *p[N]数组,删除的时候直接用delete[]p;
还有可以用C结构,如果有字串,使用类似typedef struct {
other data;
int len;
char str[1];
}EXP;分配时候EXP * p = (EXP*)new char[sizeof(otherdata) + sizeof(int) + len]//len为你要分配的字串长度,这样把内存分配在一个紧凑的位置,删除时候只需直接删除delete [] p;就把所有数据和字串一次删除了,性能要好些
for(int i = N-1;i>= 0 ;--i)
delete p[i];
忘记析构函数的特殊性了,
我现在的情况是需要在一个很大的文件中,文件有多少行逐行读取数据,一行数组占据一个Cdata,这样一次分配的话造成一个问题就是我必须知道文件有多少行,大的文件可以有60万行,所以循环一次就需要花了7.8s的时间。
不过如果实在没更好的办法,而像你这样的方法又的确能够释放内存,也只能这样了。
但是因为成员变量很多,使用的地方更多,所以我也不方便把这个CString 改成其他的类型,大家有什么办法可以给CString分配内存么?
//初始化#pragma push_maco("new")
#undef new
for(int i = 0;i<nCount;++i)
{
::new((void*)&p[i])CData;
}
#pragma pop_maco("new")//delete
for(int i = nCount - 1;i >= 0;--i)
p[i].~CData();
delete [] (char*)p;
//这样子,就能自动调用析构函数了和构造函数了,主要是要注意初始化的删除的顺序相反就很容易释放内存。
用了string代替了结构中所有的cstring,释放的内存会多一些
结贴吧,另开一贴讨论这个问题