我正在尝试实现一个内存管理系统来处理存储在地图中的指针。
struct refmanager{ //since this class is only for inheritance
//and not for polymorphism their does not need to be a virtual destructor
int count;
refmanager():count(0){}
};
我的第一个想法是将上面的结构继承到我要作为指针插入到地图中的类中。
template <class P> void ref(P ptr)
{
ptr->count+=1;
cout<<"increasing ref count\n";
}
template <class P> void deref(P ptr)
{
ptr->count-=1;
cout<<"decreasing ref count\n";
if (ptr->count==0)
delete ptr;
}
比我打算使用上面的模板函数来增加和减少引用计数。为了使系统自动化,我将使用下面的模板函数作为法线贴图方法的替换(请注意,这是不完整的,并且为我的测试用例编写了清晰的贴图方法,并且不是通用的。)
template <class M, class K, class V> void mapinsert(M &map, K key, V value)
{
ref(value);
map.insert(pair<K, V>(key, value));
}
template <class T> void clearmap(T input)
{
deref(input[1]);
input.clear();
}
从初步测试开始,这个想法很有效。但我不知道这是否会导致以后可能发生的灾难。有经验的人可以告诉我这个内存管理概念是否有用,如果没有,何时,何地以及为什么会失败?
答案 0 :(得分:2)
我只查看引用对象(delete ptr
)的空间释放,但是分配在哪里?
您必须确保每个参考对象都在堆中分配,而不是在堆栈中。
value
中的 ref(value);
是一个指针?因为value
是模板定义的类型,所以它可能不是指针。
答案 1 :(得分:0)
显然我不能把代码放在评论中。无论如何,这是对Charlies回答的回应。顺便说一句他是对的,上面的方法是可行的,但不是最安全的方法。以下是一种更安全的方法。
您可以使用以下代码生成一个refmanger类:
class refmanager{
private:
int count;
public:
refmanager():count(0){}
virtual ~refmanager() {}
void ref(refmanager* ptr)
{
ptr->count+=1;
}
void deref(refmanager* ptr)
{
ptr->count-=1;
if (ptr->count==0)
delete ptr;
}
};
refmanager类可以由需要引用其指针的类继承。
下面的代码现在只在V和T是包含具有正确格式的ref和deref方法的对象时才编译。换句话说,您确保代码在运行过程中不会意外崩溃。
template <class M, class K, class V> void mapinsert(M &map, K key, V value)
{
value->ref(value);
map.insert(pair<K, V>(key, value));
}
template <class T> void clearmap(T input)
{
input[1]->deref(input[1]);
input.clear();
}