C++二叉树插入函数指针未初始化致运行崩溃求助
嘿,我看你在跟着教程写二叉搜索树的插入函数时踩了C++指针的两个常见坑——未分配内存就直接访问指针和编译器对指针初始化的严格检查,我一步步给你拆解问题和解决办法:
1. 最严重的问题:newNode未分配内存就直接赋值
你声明了newNode这个指针,但它只是一个空的指针变量,根本没指向任何有效的nodeType对象内存空间。直接去写newNode->info = item相当于去访问一块随机的内存地址,程序不崩溃才怪!
解决办法超简单:在给newNode的成员赋值前,先用new关键字为它分配一块内存:
newNode = new nodeType<elemType>; // 先分配内存,拿到有效的对象地址 newNode->info = item; newNode->leftLink = nullptr; newNode->rightLink = nullptr;
(这里推荐用C++11标准的nullptr代替NULL,类型更安全,避免一些隐式转换的坑)
2. 编译器警告:trail未初始化
编译器提示trail可能未初始化,其实从逻辑上看,当进入else分支时,root肯定不为空,current = root后while循环至少会执行一次,trail = current一定会被执行,所以trail不会是未初始化的状态。但编译器的静态检查没这么智能,它只看到你声明trail时没给初始值。
解决办法:声明指针时直接初始化trail为nullptr,既能消除警告,也符合C++的良好编码习惯:
nodeType<elemType> *current = nullptr, *trail = nullptr, *newNode = nullptr;
修正后的完整代码
把上面的修改整合,还要注意一个容易忽略的细节:当发现元素已经存在要返回时,记得释放newNode已经分配的内存,不然会造成内存泄漏!最终代码如下:
template<class elemType> void searchTree<elemType>::insert(const elemType& item) { nodeType<elemType> *current = nullptr, *trail = nullptr, *newNode = nullptr; // 先为新节点分配内存 newNode = new nodeType<elemType>; newNode->info = item; newNode->leftLink = nullptr; newNode->rightLink = nullptr; if (root == nullptr) { root = newNode; } else { current = root; while (current != nullptr) { trail = current; if (current->info == item) { cout << "Item is already in tree, no duplicates." << endl; // 释放已分配的内存,避免泄漏 delete newNode; return; } else if (current->info > item) { current = current->leftLink; } else { current = current->rightLink; } } if (trail->info > item) { trail->leftLink = newNode; } else { trail->rightLink = newNode; } } }
关于模板的小补充
你提到对模板陌生,其实这里的searchTree是模板类,nodeType是对应的模板结构体/类,只要nodeType的定义里确实有info、leftLink、rightLink这些成员,上面的代码就能正常工作。模板的核心是“代码蓝图”,编译器会在你使用具体类型(比如searchTree<int>)时自动生成对应的具体类代码,不用太担心,多写几次就熟悉啦。
内容的提问来源于stack exchange,提问作者Cole-Peterson

