C++重载运算符使用this指针,释放内存时触发段错误
问题原因与解决方案
核心错误分析
你遇到的段错误本质是非法释放栈内存:
a和b是main函数栈上创建的局部对象,它们的生命周期由系统自动管理,不需要手动调用deletec的析构函数中调用delete left和delete right,相当于试图释放栈上的对象,这属于未定义行为,直接触发段错误- 你之前尝试
std::unique_ptr无效,是因为同样把栈对象的地址传给了它,unique_ptr析构时依然会执行非法的delete操作
针对性解决方案
根据运算树的内存管理需求,分两种场景处理:
场景1:运算树不管理叶子节点内存(叶子由外部控制生命周期)
适合输入张量(如a、b)由用户手动管理的场景,此时运算树节点仅持有指针,不负责释放:
#include <vector> using namespace std; template<typename T> struct ObjectPointers { const ObjectPointers<T>* left; const ObjectPointers<T>* right; vector<T> data; ObjectPointers(std::initializer_list<T> list) : data(list), left(nullptr), right(nullptr) {} // 析构函数不再释放left/right,因为它们指向外部管理的对象 ~ObjectPointers() = default; ObjectPointers(const ObjectPointers<T>* left, const ObjectPointers<T>* right) : left(left), right(right) {} ObjectPointers operator+(const ObjectPointers& other) const { return ObjectPointers<T>(this, &other); } }; int main() { ObjectPointers<int> a = {1, 2, 3}; ObjectPointers<int> b = {4, 5, 6}; ObjectPointers<int> c = a + b; return 0; }
场景2:运算树统一管理所有节点内存(全堆分配)
适合运算树全权控制所有节点生命周期的场景,用std::unique_ptr自动管理堆内存,避免手动释放出错:
#include <vector> #include <memory> using namespace std; template<typename T> struct ObjectPointers { unique_ptr<const ObjectPointers<T>> left; unique_ptr<const ObjectPointers<T>> right; vector<T> data; ObjectPointers(std::initializer_list<T> list) : data(list) {} // unique_ptr会自动释放堆内存,无需手动写析构函数 ~ObjectPointers() = default; ObjectPointers(unique_ptr<const ObjectPointers<T>> left, unique_ptr<const ObjectPointers<T>> right) : left(move(left)), right(move(right)) {} // 用静态方法创建加法节点,明确内存转移逻辑 static unique_ptr<ObjectPointers<T>> add(unique_ptr<ObjectPointers<T>> lhs, unique_ptr<ObjectPointers<T>> rhs) { return make_unique<ObjectPointers<T>>(move(lhs), move(rhs)); } }; int main() { auto a = make_unique<ObjectPointers<int>>({1, 2, 3}); auto b = make_unique<ObjectPointers<int>>({4, 5, 6}); auto c = ObjectPointers<int>::add(move(a), move(b)); return 0; }
内容的提问来源于stack exchange,提问作者nickk2002
相关产品推荐
相关产品推荐

