我有一棵巨大的树,其中的键内部节点是一个大的hash_map v的索引, 其中v [key]是与该键相关联的(大)记录(包括树中有多少个节点具有此键)。现在,key是一个整数。所以每个节点 有存储子项指针和整数的开销 我们可以从树中的节点中删除密钥。 我们不能将实际记录存储在树节点中(因为那将是内存耗尽)。 从节点中删除密钥时,我们需要查看v,更新计数并删除元素 (并压缩矢量)。
这迫切需要一个智能指针实现:我们在树周围有一个shared_ptr传播。 一旦引用了密钥k的最后一个节点被删除,该对象就会被破坏。
但是,我对shared_ptr的大小要求持怀疑态度。我需要一个cheep参考计数 智能柜台。我不关心并发访问。
答案 0 :(得分:2)
这是一个简单的引用计数智能指针,几年前我从网上摘取并修补了一点:
/// A simple non-intrusive reference-counted pointer.
/// Behaves like a normal pointer to T, providing
/// operators * and ->.
/// Multiple pointers can point to the same data
/// safely - allocated memory will be deleted when
/// all pointers to the data go out of scope.
/// Suitable for STL containers.
///
template <typename T> class counted_ptr
{
public:
explicit counted_ptr(T* p = 0)
: ref(0)
{
if (p)
ref = new ref_t(p);
}
~counted_ptr()
{
delete_ref();
}
counted_ptr(const counted_ptr& other)
{
copy_ref(other.ref);
}
counted_ptr& operator=(const counted_ptr& other)
{
if (this != &other)
{
delete_ref();
copy_ref(other.ref);
}
return *this;
}
T& operator*() const
{
return *(ref->p);
}
T* operator->() const
{
return ref->p;
}
T* get_ptr() const
{
return ref ? ref->p : 0;
}
template <typename To, typename From>
friend counted_ptr<To> up_cast(counted_ptr<From>& from);
private: // types & members
struct ref_t
{
ref_t(T* p_ = 0, unsigned count_ = 1)
: p(p_), count(count_)
{
}
T* p;
unsigned count;
};
ref_t* ref;
private: // methods
void copy_ref(ref_t* ref_)
{
ref = ref_;
if (ref)
ref->count += 1;
}
void delete_ref()
{
if (ref)
{
ref->count -= 1;
if (ref->count == 0)
{
delete ref->p;
delete ref;
}
ref = 0;
}
}
};
每个智能指针的存储要求是适度的:只有真实指针和引用计数。
答案 1 :(得分:1)
为什么不扩展树实现以跟踪存储在其中的密钥的计数?您需要的只是另一个散列映射(或现有散列映射的每个记录中的附加字段)以跟踪计数,并在树的添加/删除函数中添加一些逻辑以适当地更新计数。