LeetCode二叉树转链表代码遇AddressSanitizer堆释放后使用错误求助
问题修复方案
你的代码出现heap-use-after-free错误,是因为分支处理逻辑存在潜在的指针访问风险。以下是修复后的代码及说明:
class Solution { public: void flatten(TreeNode* root) { if (root == nullptr) { return; } // 递归处理左右子树,确保子树已展开为链表 flatten(root->left); flatten(root->right); // 保存原右子树的指针 TreeNode* originalRight = root->right; // 将左子树移到右子树位置,左指针置空 root->right = root->left; root->left = nullptr; // 找到当前右子树的最末端节点 TreeNode* curr = root; while (curr->right != nullptr) { curr = curr->right; } // 将原右子树接在当前右子树的末端 curr->right = originalRight; } };
修复说明
- 简化逻辑结构:移除了多余的
convert函数,直接在flatten中实现核心逻辑,减少函数调用层级,降低指针混乱的概率。 - 消除不必要分支:不管左子树是否为空,统一执行「左子树移至右侧→找最右节点→接入原右子树」的流程,避免原分支中反复修改指针导致的内存访问风险。
- 严格后序遍历顺序:先递归处理左右子树,确保子树已经被展开为单链表后,再修改当前节点的指针结构,保证拼接的子树都是合法的链表结构。
原错误原因推测
原代码中,当左子树为空时,你先将root->right设为NULL,再重新赋值为原右子树指针rgt。虽然逻辑上看似合理,但在某些测试用例中,递归过程中指针的间接修改可能导致rgt指向的内存被提前释放,后续访问时触发地址 sanitizer 的报错。简化后的逻辑避免了这种不必要的指针反复赋值,从根源上消除了潜在的内存访问问题。
内容的提问来源于stack exchange,提问作者Ramjeet Singh
相关产品推荐
相关产品推荐

