Clang静态分析器在通过共享ptr的以下实现释放后报告了内存使用情况(虽然天真,但仍然可以正常工作):
template <class T>
class Shared
{
public:
Shared()
: ptr(0) , count(0)
{
}
explicit Shared(T* otherPtr)
: ptr(0), count(0)
{
init(otherPtr);
}
template <class DerivedT>
explicit Shared(DerivedT* otherPtr)
: ptr(0), count(0)
{
init(otherPtr);
}
explicit Shared(OutRef<T> ref)
: ptr(0), count(0)
{
init(ref.ptr);
}
Shared(const Shared& other)
: ptr(other.ptr), count(other.count)
{
addShared();
}
template <class DerivedT>
Shared(const Shared<DerivedT>& other)
: ptr(other.ptr), count(other.count)
{
addShared();
}
Shared& operator = (const Shared& other)
{
Shared tmp(other);
swap(tmp);
return *this;
}
template <class DerivedT>
Shared& operator = (const Shared<DerivedT>& other)
{
Shared tmp(other);
swap(tmp);
return *this;
}
~Shared()
{
destroy();
}
operator bool() const
{
return ptr != 0;
}
void operator = (T* otherPtr)
{
set(otherPtr);
}
template <class DerivedT>
void operator = (DerivedT* otherPtr)
{
set(otherPtr);
}
void operator = (OutRef<T> ref)
{
set(ref.ptr);
}
T* operator->()
{
return ptr;
}
const T* operator->() const
{
return ptr;
}
T& operator*()
{
return *ptr;
}
const T& operator*() const
{
return *ptr;
}
template <class DerivedT>
void set(DerivedT* otherPtr)
{
if (ptr != otherPtr)
{
destroy();
init(otherPtr);
}
}
T* get()
{
return ptr;
}
const T* get() const
{
return ptr;
}
operator T*()
{
return ptr;
}
operator const T*() const
{
return ptr;
}
template <class TT>
Shared<TT> cast()
{
Shared<TT> result;
result.ptr = (TT*)ptr;
result.count = count;
result.addShared();
return result;
}
bool isLastOwner() const
{
return count && *count == 1;
}
private:
void addShared()
{
if (count)
{
*count += 1;
}
}
template <class DerivedT>
void init(DerivedT* otherPtr)
{
presume(ptr == 0);
presume(count == 0);
if (otherPtr == 0)
{
return;
}
ptr = otherPtr;
count = new Index(1);
}
void destroy()
{
if (count)
{
*count -= 1;
if (*count == 0)
{
presume(sizeof(T) > 0); //will break compilation in case of undefined T
delete ptr;
delete count;
}
}
ptr = 0;
count = 0;
}
void swap(Shared& other)
{
Swap(ptr, other.ptr);
Swap(count, other.count);
}
private:
T* ptr;
Index* count;
template <class OtherT> friend class Shared;
};
例如,如果我具有Shared f()函数并将其用作
Shared<X> a = f();
a->callSomeMethod();
在释放内存后,我得到静态分析器警告“ a”已使用。基本上,它检测到已调用destroy()方法,但无法检测到堆栈跟踪中的计数器为正(对于计数器零检查,它写入“假定条件为true”)。是否可以添加一些assert()以便它了解计数器在此处为正?还是真的是不正确的共享指针实现?