如何删除堆中返回的对象?解决operator+内存泄漏及智能指针疑问
问题解答
1. 如何删除分配的sum_obj对象?
当前代码里operator+返回的是对象值(*sum_obj),这会触发拷贝构造函数创建临时对象返回,而原堆上的sum_obj指针直接丢失,根本无法直接调用delete释放。要解决这个问题,只能调整返回逻辑:
- 修改返回类型为指针:把
operator+的返回类型改成JMP*,调用方拿到指针后手动执行delete。但这种方式会让语法变得繁琐,且依然存在忘记释放的风险。示例代码:JMP* operator+(const JMP &j) { JMP *sum_obj = new JMP("0"); sum_obj->number[0] += 1; return sum_obj; } // 调用时 JMP* temp = *a + *b; *c = *temp; delete temp; // 手动释放堆对象 - 注意:返回值的写法本身就不适合堆上分配的对象,因为原对象的指针会被丢弃,这是设计上的问题,必须调整返回方式才能解决泄漏。
2. 使用智能指针能否解决该问题?
完全可以,智能指针是解决这类堆内存管理问题的标准方案,能自动处理内存释放,避免泄漏。
方案一:用std::unique_ptr(独占式管理,优先推荐)
std::unique_ptr是独占所有权的智能指针,适合不需要共享对象的场景,性能开销极低:
#include <iostream> #include <memory> class JMP { public: std::string number; JMP() {} JMP(const char* num) : number(num) {} std::unique_ptr<JMP> operator+(const JMP &j) { auto sum_obj = std::make_unique<JMP>("0"); sum_obj->number[0] += 1; return sum_obj; } }; int main() { std::unique_ptr<JMP> a = std::make_unique<JMP>(); std::unique_ptr<JMP> b = std::make_unique<JMP>(); std::unique_ptr<JMP> c = std::make_unique<JMP>(); auto temp = *a + *b; *c = *temp; // temp离开作用域时,会自动调用delete释放堆上的sum_obj return 0; }
方案二:用std::shared_ptr(适合需要共享对象的场景)
如果后续需要多个指针共享计算结果对象,可以用std::shared_ptr,它通过引用计数管理对象生命周期:
#include <iostream> #include <memory> class JMP { public: std::string number; JMP() {} JMP(const char* num) : number(num) {} std::shared_ptr<JMP> operator+(const JMP &j) { auto sum_obj = std::make_shared<JMP>("0"); sum_obj->number[0] += 1; return sum_obj; } }; int main() { std::shared_ptr<JMP> a = std::make_shared<JMP>(); std::shared_ptr<JMP> b = std::make_shared<JMP>(); std::shared_ptr<JMP> c = std::make_shared<JMP>(); auto temp = *a + *b; *c = *temp; // 当最后一个指向sum_obj的shared_ptr销毁时,对象会自动释放 return 0; }
核心原理
智能指针封装了原始指针,在自身的析构函数中自动调用delete。当返回的智能指针对象(比如示例中的temp)离开作用域时,析构函数触发,堆上的sum_obj就会被正确释放,不会出现内存泄漏。
额外说明
对于重型数学计算对象,堆内存是合理选择,但手动管理原始指针极易引发泄漏。智能指针是C++标准库提供的成熟解决方案,既保证了内存安全,又不需要手动处理释放逻辑,完全适配重型对象的使用场景。
内容的提问来源于stack exchange,提问作者user21165505
相关产品推荐
相关产品推荐

