尝试删除堆分配int时触发delete_scalar.cpp错误,求问题定位与修复
问题分析与修复
用户代码
#include <iostream> class TEST { public: int* a = new int; TEST(int x) : a(&x) { } ~TEST() { delete a; } }; int main() { { int i = 2; TEST T(i); } std::cin.get(); }
用户问题
我尝试在TEST类中堆分配整数并销毁它,但在类的析构函数中调用delete a时,触发了delete_scalar.cpp中的错误,不清楚错误含义及修复方法,请问问题出在哪里?
问题根源
- 构造函数的初始化列表把
a的地址替换成了栈变量x的地址(x是构造函数的形参,存储在栈内存中),直接丢弃了类内初始化时堆分配的内存地址,导致那块堆内存无人释放,造成内存泄漏。 - 析构函数调用
delete a时,你试图释放栈内存——delete只能用于释放new在堆上分配的内存,释放栈内存属于非法操作,这就是触发delete_scalar.cpp报错的原因。
修复方案
方案1:正确使用堆内存(符合你的初始需求)
如果你想让a指向堆上的整数并初始化,有两种写法:
写法一:保留类内堆初始化,直接给堆内存赋值
#include <iostream> class TEST { public: int* a = new int; TEST(int x) { *a = x; // 给堆上的整数赋值,不修改a的地址 } ~TEST() { delete a; // 释放合法的堆内存 } }; int main() { { int i = 2; TEST T(i); } std::cin.get(); }
写法二:在构造函数中直接堆分配并初始化
#include <iostream> class TEST { public: int* a; TEST(int x) : a(new int(x)) // 直接堆分配内存并初始化x的值 { } ~TEST() { delete a; } }; int main() { { int i = 2; TEST T(i); } std::cin.get(); }
方案2:指向传入的栈变量(需注意生命周期)
如果确实需要让a指向传入的变量,那么不能调用delete a,同时要去掉类内的堆分配避免内存泄漏:
#include <iostream> class TEST { public: int* a; TEST(int x) : a(&x) { } ~TEST() { // 不要调用delete a,因为a指向栈内存,会由系统自动释放 } }; int main() { { int i = 2; TEST T(i); } std::cin.get(); }
⚠️ 注意:这种写法必须保证TEST对象的生命周期不超过传入变量的生命周期,否则a会变成野指针,访问它会触发未定义行为。
内容的提问来源于stack exchange,提问作者user20295136
相关产品推荐
相关产品推荐

