ln *_* vv 1 c++ memory-management double-free assignment-operator delete-operator
当我编写一个演示字符串类时,在复制赋值函数中,我尝试在复制之前通过“删除此”来清除自身。但它失败了。
Str &operator=(const Str &s) {
if (this != &s) { // self-assignment check
//delete this; //cannot run as I imagine
this->~Str();
_size = s._size;
_str = new char[_size + 1];
memcpy(_str, s._str, _size + 1);
}
return *this;
}
~Str() {
_size = 0;
delete[] _str;
}
Run Code Online (Sandbox Code Playgroud)
linux 告诉我的
双释放或损坏(出)中止(核心转储)
delete x;相当于x->~T();其次operator delete(x)(与 类似free(x),但可能与之不兼容)。
x->~T();是一个危险的工具。在这种情况下,必须紧跟new(this) T(...);(placement-new) 来调用构造函数,否则当前对象被认为是“死的”,并且与它的任何交互都会导致未定义的行为。
但即使你确实调用了placement-new,它也可能会抛出异常。然后该对象仍然处于死亡状态,并且当调用者尝试再次销毁已经死亡的对象时,它会得到 UB。
结论:x->~T();很难正确使用,请使用其他东西。
要么编写一个与析构函数执行相同操作的函数,然后调用它。与析构函数不同,调用该对象后不会被视为已死亡,因此不需要放置新对象。
或者使用复制和交换习惯用法。将作业写为:
Str &operator=(Str s) noexcept
{
std::swap(_str, s._str);
std::swap(_size, s._size);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
这是撰写作业的通用方法。它既可以用作复制分配,也可以用作移动分配,并且是异常安全的,等等。
| 归档时间: |
|
| 查看次数: |
122 次 |
| 最近记录: |