如何修复C++二叉搜索树指针引发的内存泄漏及std::bad_alloc报错
问题诊断
核心原因是你的自定义ABB二叉搜索树类未实现析构函数释放动态申请的节点内存,导致每次make_experiment函数执行结束后,局部ABB abb对象销毁时,所有通过new创建的node节点都没有被回收,持续累积内存泄漏。
按单文件百万行插入操作计算,每次实验至少占用几十MB内存,累积到250次时总占用可达几GB,最终内存耗尽抛出std::bad_alloc异常,完全符合你遇到的故障现象。
修复方案
1. 给ABB类新增节点释放逻辑
首先在ABB类的private域添加递归释放子树的辅助函数声明:
class ABB{ private: node* root; node* insert(uint x, node* t); int find(node* t, uint x); // 新增:递归释放指定子树所有节点的辅助函数 void destroy(node* t); public: ABB(); ~ABB(); // 新增:析构函数声明 void insert(uint x); int search(uint x); };
然后实现辅助函数和析构函数:
void ABB::destroy(node* t) { if (t != NULL) { // 先递归释放左右子树,再释放当前节点 destroy(t->left); destroy(t->right); delete t; } } // 析构函数:释放整棵树的所有节点 ABB::~ABB() { destroy(root); }
修改完成后,每次make_experiment函数结束、abb对象销毁时,会自动调用析构函数释放所有节点内存,不会再出现内存累积泄漏的问题。
2. 可选安全优化
如果后续代码可能存在ABB对象的拷贝操作,建议禁用默认的拷贝构造和拷贝赋值函数,避免浅拷贝导致同一块节点内存被多次释放:
public: ABB(const ABB&) = delete; ABB& operator=(const ABB&) = delete;
额外注意
你当前的BST实现默认忽略重复值插入,如果实验逻辑需要支持重复值,需要额外调整插入逻辑;如果后续需要支持节点删除操作,删除对应节点时也要手动调用delete释放内存,避免局部泄漏。
内容的提问来源于stack exchange,提问作者vdaiep
相关产品推荐
相关产品推荐

