C++自定义Vector类重载+运算符临时对象析构内存错误问题求解
问题核心原因
你遇到的SIGABRT是**双重释放(double free)**错误,根源是你的Vector类没有遵循C的三五法则,未显式实现拷贝构造函数、拷贝赋值运算符。C默认生成的这两个函数只会执行浅拷贝,直接复制内部裸指针的地址,不会申请新内存拷贝指针指向的实际数据。
完整错误触发流程:
operator+内创建的局部output对象持有一块动态分配的内存- 返回
output时,默认拷贝构造函数直接将output的指针值复制给返回临时对象,随后output析构释放该内存 - 执行
*vector3 = 临时对象时,默认拷贝赋值运算符又将临时对象的指针值复制给vector3的内部指针,临时对象生命周期结束后析构,第二次释放同一块内存 - 最后
delete vector3时,析构函数尝试释放已经被释放过的内存,直接触发崩溃
通用修复方案
该方案对所有返回自定义类对象的运算符重载都生效:
1. 修复默认构造函数
你当前的默认构造函数未初始化成员变量,会导致野指针问题,先修改:
template <class T> Vector<T>::Vector() : x(0), vector(nullptr) {}
2. 显式实现拷贝构造函数
拷贝时申请新内存复制实际数据,避免两个对象持有同一块内存:
template <class T> Vector<T>::Vector(const Vector<T>& other) { x = other.x; vector = new T[x]; for (unsigned i = 0; i < x; ++i) { vector[i] = other.vector[i]; } }
3. 显式实现拷贝赋值运算符
处理赋值场景的内存管理,规避自赋值问题:
template <class T> Vector<T>& Vector<T>::operator=(const Vector<T>& other) { if (this == &other) return *this; // 跳过自赋值场景 delete[] vector; // 先释放当前对象原有内存 x = other.x; vector = new T[x]; for (unsigned i = 0; i < x; ++i) { vector[i] = other.vector[i]; } return *this; }
可选优化:实现移动语义(C++11及以上)
如果要减少临时对象的内存拷贝开销,可以补充实现移动构造和移动赋值运算符,直接转移临时对象的内存所有权:
// 移动构造 template <class T> Vector<T>::Vector(Vector<T>&& other) noexcept { x = other.x; vector = other.vector; // 将原对象指针置空,避免析构时释放被转移的内存 other.x = 0; other.vector = nullptr; } // 移动赋值 template <class T> Vector<T>& Vector<T>::operator=(Vector<T>&& other) noexcept { if (this == &other) return *this; delete[] vector; x = other.x; vector = other.vector; other.x = 0; other.vector = nullptr; return *this; }
完成以上修改后,所有算术运算符(-/*//等)的重载都可以正常返回临时对象,不会再出现内存重复释放的问题。
内容的提问来源于stack exchange,提问作者Darvlinig
相关产品推荐
相关产品推荐

