繁体   English   中英

在大型项目上,复制分配操作员内存泄漏

[英]Copy assignment operator memory leak, on big project

在过去的几个月中,我一直在从事一个大型项目。 现在,我终于完成了该项目。 但是在我的副本分配运算符中,我发生了内存泄漏。 Valgrind表明泄漏的是data_的原始值。

这是我的复印分配操作员代码。

Value& Value::operator=(const Value& r)
{
  data_ = copy(r.data_);
  delete data_; 
  return *this;
}

任何人都可以帮助我解决这个问题? 我真的很感激。

我相信你想这样写:

delete data_;     //here it makes sense: delete the current value
data_ = copy(r.data_);  //copy now

不是这个:

data_ = copy(r.data_); //LEAK, as data_ is pointing to current value
delete data_;         //here you're deleting the copied one

确保data_始终指向有效内存-否则有条件地将其删除。

这没有道理:

data_ = copy(r.data_);
delete data_; 

因为如果data_被指向分配的内存,你覆盖它

data_ = copy(r.data_);

然后删除新复制的区域,则出现内存泄漏(您不再可以引用原来拥有的已分配内存)。

删除刚刚复制的内存有很大的好处:如果您曾经实际使用_data指针,您将获得未定义的行为。

你可能想写

template <typename T>
Value<T>& Value<T>::operator=(const Value<T>& r)
{
  delete data_; // Free this object's memory
  data_ = copy(r.data_); // And now get a copy (hopefully a deep one) of the new memory
  return *this;
}

一个小警告:即使固定,以上代码也没有强大的异常保证 :如果由于任何原因内存复制失败,您可能会遇到一个不一致的对象(因为data_已经被删除)。

问题data_在复制后立即删除!

  data_ = copy(r.data_);
  delete data_;          <<< PROBLEM

最好的解决方案可能是采用“复制和交换”的成语( 什么是“复制和交换”的成语? )。

template <typename T>
Value<T>& Value<T>::operator=(const Value<T> rhs)  // NOTE: pass by value
{
  swap(data_, rhs.data_);  // either std::swap or a custom swap,
                           // hard to say without knowing the type of data_
  return *this;
}

另一种选择是对OP代码的直接增强,如下所示。

template <typename T>
Value<T>& Value<T>::operator=(const Value<T>& r)
{
  // 1) Allocate new data. If, for some reason, the allocation throws,
  // the original data_ stays intact. This offers better
  // exception safety.
  ... new_data = ...;

  // 2) Copy r.data to new_data (note: deep copy desired)
  new_data = copy(r.data_); 

  // 3) Destroy original data_
  delete data_;

  // 4) Point data_ to new_data
  data_ = new_data;

  return *this;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM