我执行在Linux下我自己的图形库(Fedora 10中和CentOS 5)用gcc 4.3.2和使用STL容器,然后我发现了一些问题与记忆。当我构建我的图形时,我使用了足够多的内存来查看top或其他内存使用工具。我敢肯定,我重新分配内存(我一次又一次地回顾了代码,我使用的valgrind检查内存泄漏),但内存仍然在使用(我可以在顶部或执行cat/proc查看此/ meminfo),当我再次创建图形时,它不会增加内存使用量,显然会重新使用分配的内存。STL容器内存问题
经过几天的调试,我创建了一个非常简单的代码,它有相同的问题。
#include <iostream>
#include <list>
// Object that occupies 128KB.
// Data is not important.
class MyObject
{
public:
int * a;
int * b;
int * c;
int * d;
MyObject()
{
a = new int[ 8192 ];
b = new int[ 8192 ];
c = new int[ 8192 ];
d = new int[ 8192 ];
}
MyObject(const MyObject & m)
{
a = new int[ 8192 ];
b = new int[ 8192 ];
c = new int[ 8192 ];
d = new int[ 8192 ];
}
~MyObject()
{
delete [] a;
delete [] b;
delete [] c;
delete [] d;
}
void operator=(const MyObject &m)
{
//Do nothing.
}
};
typedef std::list<MyObject> list_t;
#define MB_TO_ALLOC 1000 // Size in MB that the program must alloc.
#define SLEEP_TIME 5 // Time in seconds that the program must wait until go to another step.
// It's used to give sufficient time for tools update the memory usage
int main()
{
std::cout << "Alloc..." << std::endl;
list_t * list = new list_t();
// Number of objects for alloc MB_TO_ALLOC amount of memory
int nObjects = MB_TO_ALLOC * 1024/128;
for(int i = 0; i < nObjects; ++i)
list->push_back(MyObject());
std::cout << SLEEP_TIME << "s to Dealloc..." << std::endl;
// Wait some time for a tool (like top) to update the memory usage
sleep(SLEEP_TIME);
std::cout << "Dealloc..." << std::endl;
delete list;
std::cout << SLEEP_TIME << "s to Alloc..." << std::endl;
// Wait some time for a tool (like top) to update the memory usage
sleep(SLEEP_TIME);
//Repeats the procedure for evaluating the reuse of memory
std::cout << "Alloc..." << std::endl;
list = new list_t();
for(int i = 0; i < nObjects; ++i)
list->push_back(MyObject());
std::cout << SLEEP_TIME << "s to Dealloc..." << std::endl;
sleep(SLEEP_TIME);
delete list;
}
我试图用简单的数组或我自己的列表类,但在这些情况下,内存通常释放。
有谁知道发生了什么事?如何防止这个内存被“保留”?
谢谢!
- 布鲁诺卡波尼
请注意,当你分配在车队内存和可用它在析构函数,你的代码是不是异常安全的,因为四个分配中的任何一个可能失败(如果,例如,第三分配失败,对象'一'和'b'将被泄漏)。在这种情况下最好使用像boost :: scoped_ptr这样的智能指针(它有一个非常简单的实现)。 – 2010-10-01 18:46:09
@James在这里我只是简单地使用表格:没有必要为这个演示动态地分配它们。也不需要动态地分配'list'。恐怕'Bruno'来自Java/C#背景,非常需要使用'new'。 – 2010-10-01 18:58:52
'MyObject'需要一个赋值操作符。否则,您将删除相同的内存块两次。 – 2010-10-01 19:00:17