C++继承类代码触发free(): double free detected错误排查求助
C++继承代码中的双重释放错误修复
问题描述
编写带有继承关系的C++代码时,无语法错误但运行触发free(): double free detected in tcache 2错误,程序终止。
原代码
#include <iostream> #include <vector> class Shape { public: Shape(int size) : size(size) { data = new int[size]; for (int i = 0; i < size; ++i) { data[i] = i; } } virtual ~Shape() { delete[] data; } virtual void printInfo() const { std::cout << "Shape with size " << size << std::endl; } protected: int* data; int size; }; class Circle : public Shape { public: Circle(int size, int radius) : Shape(size), radius(radius) {} ~Circle() { delete[] data; } void printInfo() const override { std::cout << "Circle with size " << size << " and radius " << radius << std::endl; } private: int radius; }; void printShapeInfo(const Shape& shape) { shape.printInfo(); } int main() { std::vector<Shape*> shapes; shapes.push_back(new Circle(5, 3)); shapes.push_back(new Shape(7)); for (const Shape* shape : shapes) { printShapeInfo(*shape); delete shape; } return 0; }
预期输出
Circle with size 5 and radius 3 Shape with size 7
实际输出
Circle with size 5 and radius 3 free(): double free detected in tcache 2 Aborted
错误原因
当delete一个Circle对象时,由于基类Shape的析构函数是虚函数,会先调用派生类Circle的析构函数,再调用基类Shape的析构函数。两处析构函数都执行了delete[] data;,导致同一块堆内存被释放两次,触发双重释放错误。
修复方案
删除Circle类中的自定义析构函数,让编译器自动生成默认析构函数即可。基类的虚析构函数已经负责释放data,无需派生类重复操作。
修复后的Circle类代码:
class Circle : public Shape { public: Circle(int size, int radius) : Shape(size), radius(radius) {} void printInfo() const override { std::cout << "Circle with size " << size << " and radius " << radius << std::endl; } private: int radius; };
额外建议
为避免手动管理内存的风险,推荐使用智能指针(如std::unique_ptr)代替原始指针,自动处理内存释放,彻底规避此类错误。修改后的main函数示例:
int main() { std::vector<std::unique_ptr<Shape>> shapes; shapes.push_back(std::make_unique<Circle>(5, 3)); shapes.push_back(std::make_unique<Shape>(7)); for (const auto& shape : shapes) { printShapeInfo(*shape); } // 无需手动delete,智能指针会自动释放内存 return 0; }
内容的提问来源于stack exchange,提问作者Mishael Jawaid
相关产品推荐
相关产品推荐

