Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于deque容器析构函数中可能会导致内存泄漏的问题 #143

Open
myc13381 opened this issue Jan 10, 2024 · 3 comments
Open

Comments

@myc13381
Copy link

~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函数的调用用于释放内存,这样才能在析构函数中实现正确的内存释放。
以上仅是我个人的理解,如果理解有误还请指正。

@HuiQianPeng0401
Copy link

我也注意到了这个问题,调用destroy后deque的内存块应该并未释放吧,感觉应该加上deallocate来释放申请的内存块。

@Alinshans
Copy link
Owner

对的 相信你自己的思考

@myc13381
Copy link
Author

myc13381 commented Mar 6, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants