C++中delete this与this->~Obj的区别及赋值运算符双释放异常排查
拷贝赋值运算符中delete this与显式调用析构函数的区别及异常原因
编写自定义Str字符串类的拷贝赋值运算符时,尝试用delete this清理自身后执行拷贝操作会触发内存错误,改用显式调用析构函数this->~Str()则正常运行。
问题代码
Str &operator=(const Str &s) { if (this != &s) { // 自赋值检查 //delete this; // 无法正常运行 this->~Str(); _size = s._size; _str = new char[_size + 1]; memcpy(_str, s._str, _size + 1); } return *this; } ~Str() { _size = 0; delete[] _str; }
报错信息
double free or corruption (out)
Aborted (core dumped)
核心区别
delete this的行为:- 先调用对象的析构函数,释放对象内部托管的资源(如本例中的
_str数组) - 随后会释放当前对象本身占用的堆内存(即
this指针指向的内存块)
- 先调用对象的析构函数,释放对象内部托管的资源(如本例中的
- 显式调用
this->~Str()的行为:
仅执行析构函数内的逻辑,释放对象内部的资源,但不会释放对象本身占用的内存
异常原因
使用delete this时,错误的根源在于:
- 执行
delete this后,析构函数先释放了_str,接着对象自身的内存被系统回收 - 后续的
_size = s._size、_str = new char[...]都是在已被释放的内存上进行写操作,属于非法内存访问 - 当赋值运算符返回
*this后,程序后续对该对象的任何操作(比如对象生命周期结束时自动调用析构函数)都会触发重复释放内存,最终导致double free or corruption错误
而显式调用析构函数时:
- 仅释放了内部的
_str资源,对象本身的内存依然有效 - 后续可以正常重新初始化
_size和分配新的_str内存,对象的生命周期不受影响,不会出现非法访问或重复释放的问题
内容的提问来源于stack exchange,提问作者ln vv
相关产品推荐
相关产品推荐

