[英]Copy assignment operator memory leak, on big project
I have been working on a big project for the past few months. 在过去的几个月中,我一直在从事一个大型项目。 Now I'm finally done with that project. 现在,我终于完成了该项目。 But in my copy assignment operator I have a memory leak. 但是在我的副本分配运算符中,我发生了内存泄漏。 Valgrind shows that it's the original value of data_ that leaks. Valgrind表明泄漏的是data_的原始值。
Here is my copy assignment operator code. 这是我的复印分配操作员代码。
Value& Value::operator=(const Value& r)
{
data_ = copy(r.data_);
delete data_;
return *this;
}
Anyone that can help me with this problem? 任何人都可以帮助我解决这个问题? I would really appreciate it. 我真的很感激。
I believe you wanted to write this: 我相信你想这样写:
delete data_; //here it makes sense: delete the current value
data_ = copy(r.data_); //copy now
not this one: 不是这个:
data_ = copy(r.data_); //LEAK, as data_ is pointing to current value
delete data_; //here you're deleting the copied one
Make sure that data_
always points to a valid memory — else delete it conditionally. 确保data_
始终指向有效内存-否则有条件地将其删除。
This doesn't make sense: 这没有道理:
data_ = copy(r.data_);
delete data_;
because if data_
was pointing to allocated memory and you overwrite it with 因为如果data_
被指向分配的内存,你覆盖它与
data_ = copy(r.data_);
and then delete the newly copied area, you have a memory leak (you can no longer refer to the allocated memory you originally had). 然后删除新复制的区域,则出现内存泄漏(您不再可以引用原来拥有的已分配内存)。
Big bonus for deleting the just-copied memory: if you ever were to actually use the _data
pointer you'll get undefined behavior. 删除刚刚复制的内存有很大的好处:如果您曾经实际使用_data
指针,您将获得未定义的行为。
You probably meant to write 你可能想写
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;
}
A small caveat: the above code even if fixed has no strong exception guarantee : if memory copy fails for whatever reason, you might end up with an inconsistent object (since data_
has already been deleted). 一个小警告:即使固定,以上代码也没有强大的异常保证 :如果由于任何原因内存复制失败,您可能会遇到一个不一致的对象(因为data_
已经被删除)。
The problem is that data_
is deleted right after it is copied! 问题是data_
在复制后立即删除!
data_ = copy(r.data_);
delete data_; <<< PROBLEM
The best solution may be to employ copy-and-swap idiom ( What is the copy-and-swap idiom? ). 最好的解决方案可能是采用“复制和交换”的成语( 什么是“复制和交换”的成语? )。
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;
}
Another alternative, a direct enhancement to OP's code, may be the following. 另一种选择是对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.