ASAN:将二叉树平展为链表时释放后堆使用
ASAN: heap-use-after-free when flattening a binary tree to a linked list
这是一个Leetcode问题,将二叉树展平到链表。
我的解决方案非常简单。对于节点root
,root->right
推送到堆栈上。将root->left
设置为root->right
,并将root->left
设置为 NULL。
我收到运行时错误:
地址清理器:在 PC 上的地址0x603000000108释放后堆使用 0x00000046bf70 bp 0x7ffc5d6c5f70 sp 0x7ffc5d6c5f68
导致错误的原因是什么?
这是我的代码:
class Solution {
public:
void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s){
if(root == NULL){
if(s.empty()) return;
else{
TreeNode* newroot = s.top();
s.pop();
pre->right = newroot;
flat_tree(pre, newroot,s);
}
}else{
if(root->left == NULL) {
flat_tree(root, root->right, s);
}else if(root->right == NULL){
root->right = root->left;
flat_tree(root, root->right, s);
}else{
TreeNode* right = root->right;
root->right = root->left;
s.push(right);
flat_tree(root, root->right, s);
}
}
}
void flatten(TreeNode* root) {
stack<TreeNode*> s;
flat_tree(NULL ,root,s);
}
};
这非常接近。在将左节点指针移动到根的右侧后,需要将其清空,从而防止当测试套件遵循指向同一内存位置的两个指针时发生的双释放堆损坏。
这是工作代码:
void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s){
if(root == NULL){
if(s.empty()) return;
else{
TreeNode* newroot = s.top();
s.pop();
pre->right = newroot;
flat_tree(pre, newroot,s);
}
}else{
if(root->left == NULL) {
flat_tree(root, root->right, s);
}else if(root->right == NULL){
root->right = root->left;
root->left = NULL; /* set the left pointer to null */
flat_tree(root, root->right, s);
}else{
TreeNode* right = root->right;
root->right = root->left;
root->left = NULL; /* do the same here */
s.push(right);
flat_tree(root, root->right, s);
}
}
}
我还建议重组分支以避免重复逻辑:
void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s) {
if (root) {
if (root->right) {
s.push(root->right);
}
root->right = root->left;
root->left = NULL;
flat_tree(root, root->right, s);
}
else if (!s.empty()) {
pre->right = s.top();
s.pop();
flat_tree(pre, pre->right, s);
}
}
相关文章:
- 反向给定链表中的K节点
- 如果没有malloc,链表实现将失败
- 文本文件中的单词链表
- 努力将整数转换为链表。不知道我在这里做错了什么
- 链表,反向函数,数据结构
- 使用std::list创建循环链表
- 链表的泛型函数remove()与成员函数remove)
- 未分配被释放的指针(将堆栈实现为链表时)
- 使用析构函数释放链表
- ASAN:将二叉树平展为链表时释放后堆使用
- 循环链表的内存错误:未分配正在释放的指针
- 如何从链表上的节点为分配的类释放内存
- 释放链表节点时出现分段错误
- (C++ 错误:未分配正在释放的指针)为链表
- “算子删除”如何为链表节点释放内存块
- 删除链表中的节点后释放分配的空间
- 链表释放内存-分段错误
- 双链表收到错误"未分配正在释放的指针"
- 关于从内存中释放链表的析构函数的逻辑和作用域的问题
- C ++链表不释放内存 - 寻找快速代码审查