gpt4 book ai didi

c++ - 自身共享指针的析构函数中的段错误

转载 作者:搜寻专家 更新时间:2023-10-31 01:14:31 33 4
gpt4 key购买 nike

出于培训目的,我尝试编写自己的智能指针,模仿 std::shared_ptr .我有一个 static std::map<void *, int> ref_track跟踪是否仍有共享指针引用内存中的某个 block 。

我的概念是这样的:

template <typename PType>
class shared_ptr
{
public:
shared_ptr()
: value_(nullptr), ptr_(nullptr)
{}

template <typename T>
explicit shared_ptr(T * ptr)
: shared_ptr()
{
reset(ptr);
}

template <typename T>
shared_ptr(shared_ptr<T> const & other)
: shared_ptr()
{
reset(other.get());
}

~shared_ptr()
{
reset();
}

void reset()
{
if(value_)
{
delete value_; // Segmentation fault here!
value_ = 0;
ptr_ = 0;
}
}

template <typename T>
void reset(T * ptr)
{
reset();
if(ptr)
{
value_ = new shared_ptr_internal::storage_impl<
T
>(ptr);
ptr_ = ptr;
}
}

PType * get() const
{
return ptr_;
}

typename shared_ptr_internal::ptr_trait<PType>::type operator *()
{
return *ptr_;
}

private:
shared_ptr_internal::storage_base * value_;
PType * ptr_;
};

在运行我的测试套件时,我注意到

shared_ptr<int> a(new int(42));
a.reset(new int(13));

工作正常,但是

shared_ptr<int> a(new int(42));
a = shared_ptr<int>(new int(13));

导致问题:*a0而不是 13 , 和 delete value_a 的析构函数中因段错误而崩溃.我在源代码中用注释标记了崩溃。

使用到的内部类是

namespace shared_ptr_internal
{

typedef std::map<void *, int> ref_tracker;
typedef std::map<void *, int>::iterator ref_tracker_iterator;
typedef std::pair<void *, int> ref_tracker_entry;

static ref_tracker ref_track;

struct storage_base
{
virtual ~storage_base() {}
};

template <typename PType>
struct storage_impl : storage_base
{
storage_impl(PType * ptr)
: ptr_(ptr)
{
ref_tracker_iterator pos = ref_track.find(ptr);
if(pos == ref_track.end())
{
ref_track.insert(
ref_tracker_entry(ptr, 1)
);
}
else
{
++pos->second;
}
}

~storage_impl()
{
ref_tracker_iterator pos = ref_track.find(ptr_);
if(pos->second == 1)
{
ref_track.erase(pos);
delete ptr_;
}
else
{
--pos->second;
}
}

private:
PType * ptr_;
};

template <typename PType>
struct ptr_trait
{
typedef PType & type;
};

template <>
struct ptr_trait<void>
{
typedef void type;
};
}

对于大量的源代码感到抱歉,但我真的不知道如何进一步缩小范围。对于可能导致段错误的任何想法,以及为什么在手动使用重置时不会发生这种情况,我将不胜感激。

更新

我的(不工作的)赋值运算符:

template <typename T>
shared_ptr<PType> & operator =(shared_ptr<T> const & other)
{
if(this != &other)
{
value_ = nullptr;
ptr_ = nullptr;
reset(other.get());
}
return *this;
}

最佳答案

您缺少赋值运算符。

这意味着在下面的代码中:

a = shared_ptr<int>(new int(13));

一个临时的共享指针被创建;然后默认赋值运算符简单地将指针复制到a,而不释放旧值或更新引用计数;然后临时删除该值,留下带有悬挂指针的 a

关于c++ - 自身共享指针的析构函数中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11292298/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com