MyTinySTL
MyTinySTL copied to clipboard
关于deque容器析构函数中可能会导致内存泄漏的问题
~deque()
{
if (map_ != nullptr)
{
clear();
data_allocator::deallocate(*begin_.node, buffer_size);
*begin_.node = nullptr; // 内存没有泄漏???clear操作并没有释放内存,应该是写错了
map_allocator::deallocate(map_, map_size_);
map_ = nullptr;
}
}
上述为deque的析构函数,其内部调用了clear函数,但是clear函数内部只调用了data_allocator::destroy
函数,此函数应该只复制元素析构函数的调用而不释放指针指向的内存。此外clear
函数内部也调用了shrink_to_fit()
函数,该函数只是将duque中两头额外的缓冲区内存释放,而内部已使用过的缓冲区并不会释放。析构函数最后只释放了begin_所在缓冲区指针指向的内存空间,这样begin之后的缓冲区(如果存在)将不会被释放,这应该会导致内存泄漏。下面附上相关函数的代码,其中有些注释是我自己写上去的。
// 清空 deque 主要操作是将deque中的全部元素析构,并将deque瘦身(删去前后未使用的空间)
template <class T>
void deque<T>::clear()
{
// clear 会保留头部的缓冲区
for (map_pointer cur = begin_.node + 1; cur < end_.node; ++cur)
{
data_allocator::destroy(*cur, *cur + buffer_size); // 为deque中的元素调用析构函数来销毁对象
}
if (begin_.node != end_.node)
{ // 有两个以上的缓冲区
mystl::destroy(begin_.cur, begin_.last);
mystl::destroy(end_.first, end_.cur);
}
else
{
mystl::destroy(begin_.cur, end_.cur);
}
shrink_to_fit();
end_ = begin_;
}
// 减小容器容量
template <class T>
void deque<T>::shrink_to_fit() noexcept
{
// 至少会留下头部缓冲区???
for (auto cur = map_; cur < begin_.node; ++cur)
{
data_allocator::deallocate(*cur, buffer_size);
*cur = nullptr;
}
for (auto cur = end_.node + 1; cur < map_ + map_size_; ++cur)
{
data_allocator::deallocate(*cur, buffer_size);
*cur = nullptr;
}
}
我认为正确的做法是在clear内部合适的位置加上data_allocator::deallocate
函数的调用用于释放内存,这样才能在析构函数中实现正确的内存释放。
以上仅是我个人的理解,如果理解有误还请指正。
我也注意到了这个问题,调用destroy后deque的内存块应该并未释放吧,感觉应该加上deallocate来释放申请的内存块。
对的 相信你自己的思考
感谢作者回复
⊙▽⊙ @.***
------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2024年3月6日(星期三) 下午2:26 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [Alinshans/MyTinySTL] 关于deque容器析构函数中可能会导致内存泄漏的问题 (Issue #143)
对的 相信你自己的思考
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>