我執行在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