寫模板的時候,模板的限制讓YourClass [BUF]mem_pool
這樣簡單的辦法失效了,我就問老師該如何捕捉內存然後“自動”管理。
老師說:C++的缺陷就在這裏,你不能自己讓內存釋放。
於是神說:要讓內存管理出現。
本文只是簡單的內存管理(按照map的能力,同時存在十萬級別的指針沒有太大問題),如果你想要項目級別的內存管理,還是算了吧。
只需要讓所有需要內存管理的類繼承MemoryManagable
這個屬性即可。
#define DEBUG
#define MEMMANAGER
#include <iostream>
#include <map>
# ifdef DEBUG
int globtest = 0;
# endif
namespace MatrixSpace
{
...
// 定義一個基類,利用基類指針可以指向子類指針的特性
class MemoryManagable
{
public:
MemoryManagable() {}
virtual ~MemoryManagable() {}
};
//讓 Matrix繼承MemoryManagable的特性
template <typename MatrixType>
class Matrix: public MemoryManagable
{
...
};
}
// 內存管理器
class MemoryManager
{
private:
std::map<MatrixSpace::MemoryManagable*, bool> mem_maps;
public:
void addToMap(MatrixSpace::MemoryManagable* mat_p)
{
if (mem_maps.count(mat_p)) {
throw std::domain_error("This pointer already registered in memory manager!!");
}
mem_maps[mat_p] = true;
return ;
}
void deleteFromMap(MatrixSpace::MemoryManagable* mat_p)
{
if (!mem_maps.count(mat_p)) {
throw std::out_of_range("This pointer is not in memory manager now..");
}
try {
delete mat_p;
mem_maps.erase(mat_p);
} catch (...) {
throw ;
}
return ;
}
void clearMap()
{
for (auto node : mem_maps) {
try {
delete node.first;
} catch (...) {
throw ;
}
}
mem_maps.clear();
return ;
}
} mem_manager;
namespace MatrixSpace
{
...
Matrix <MT> *res_mat = new Matrix <MT>(row, col);
//在你需要的地方加上對指針的管理
# ifdef MEMMANAGER
mem_manager.addToMap(res_mat);
# endif
...
}
using namespace MatrixSpace;
int main()
{
std::ios::sync_with_stdio(false);
using std::cout;
using std::endl;
Matrix <int> *A = new Matrix <int>(4, 5);
mem_manager.addToMap(A);
Matrix <int> *B = new Matrix <int>(4, 5);
mem_manager.addToMap(B);
cout << "Please input a Matrix <int> (4 * 5)" << endl;
A->initfs();
cout << "Please input a Matrix <int> (4 * 5)" << endl;
B->initfs();
(*A)[0][0] = 123;
Matrix <int> *C = (*((*A) + (*B))) + (*A);
cout << "A+B:" << endl << *C << endl;
// delete C;
C = nullptr;
C = (*A) - (*B);
cout << "A-B:" << endl << *C << endl;
C = nullptr;
A = nullptr;
B = nullptr;
# ifdef MEMMANAGER
//在不需要所有結果的時候,直接清除
mem_manager.clearMap();
# endif
# ifdef DEBUG
cout << globtest << endl;
# endif
return 0;
}
mem_manager
可以不止有一個,所以繼續寫的話,還是可以擴展一二的。