0
点赞
收藏
分享

微信扫一扫

heap-use-after-free在leetcode里会报错但在playground里就没有

  1. 修剪二叉搜索树 - 力扣(LeetCode)
    https://leetcode-cn.com/problems/trim-a-binary-search-tree/submissions/

我的答卷:

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (root == NULL) return root;
        if (!juger(root->val, low, high)) {
            if (root->left == NULL && root->right == NULL) {
                delete root;
                // return NULL;
                return trimBST(NULL, low, high);
            }
            if (root->left != NULL && root->right == NULL) {
                // auto temp = root->left;
                TreeNode* temp = new TreeNode; 
                temp = root->left;
                delete root;
                // return temp;
                return trimBST(temp, low, high);
            }
            if (root->left == NULL && root->right != NULL) {
                // auto temp = root->right;
                TreeNode* temp = new TreeNode;
                temp = root->right;
                delete root;
                // return temp;
                return trimBST(temp, low, high);
            }
            if (root->left != NULL && root->right != NULL) {
                // auto temp = root->left;
                // auto node = root->right;
                // auto node1 = root->right;
                TreeNode* temp = new TreeNode;
                TreeNode* node = new TreeNode;
                TreeNode* node1 = new TreeNode;
                temp = root->left;
                node = root->right;
                node1 = root->right;

                while (node->left != NULL) node = node->left;
                node->left = temp;
                delete root;
                // return node1;
                return trimBST(node1, low, high);
            }
        } else {
            // root->left = trimBST(root->left, low, high);
            if (root->left) root->left = trimBST(root->left, low, high);
            // root->right = trimBST(root->right, low, high);
            if (root->right) root->right = trimBST(root->right, low, high);
        }   
        return root;  
    }

    bool juger(int num, int low, int high) {
        if (num > high) return false;
        if (num < low)  return false;
        return true;
    }
};

报错内容:
输入端——

[1,null,2]
2
4

输出端

=================================================================
==42==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000258 at pc 0x00000037c905 bp 0x7fff9cd04450 sp 0x7fff9cd04448
READ of size 8 at 0x603000000258 thread T0
    #3 0x7fd7208fb0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
0x603000000258 is located 8 bytes inside of 24-byte region [0x603000000250,0x603000000268)
freed by thread T0 here:
    #3 0x7fd7208fb0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
previously allocated by thread T0 here:
    #4 0x7fd7208fb0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Shadow bytes around the buggy address:
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff8000: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
  0x0c067fff8010: fd fa fa fa 00 00 00 07 fa fa fd fd fd fa fa fa
  0x0c067fff8020: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa
  0x0c067fff8030: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
=>0x0c067fff8040: fd fa fa fa fd fd fd fa fa fa fd[fd]fd fa fa fa
  0x0c067fff8050: 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==42==ABORTING

如果根的值不在输入范围内,整个代码就会出问题;
但别的节点不在输入范围内,代码就marche bien.

后来去playground,就没问题

我也记录在github里:

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (root == NULL) return root;
        if (!juger(root->val, low, high)) {
            if (root->left == NULL && root->right == NULL) {
                delete root;
                // return NULL;
                return trimBST(NULL, low, high);
            }
            if (root->left != NULL && root->right == NULL) {
                // auto temp = root->left;
                TreeNode* temp = new TreeNode; 
                temp = root->left;
                delete root;
                // return temp;
                return trimBST(temp, low, high);
            }
            if (root->left == NULL && root->right != NULL) {
                // auto temp = root->right;
                TreeNode* temp = new TreeNode;
                temp = root->right;
                delete root;
                // return temp;
                return trimBST(temp, low, high);
            }
            if (root->left != NULL && root->right != NULL) {
                // auto temp = root->left;
                // auto node = root->right;
                // auto node1 = root->right;
                TreeNode* temp = new TreeNode;
                TreeNode* node = new TreeNode;
                TreeNode* node1 = new TreeNode;
                temp = root->left;
                node = root->right;
                node1 = root->right;

                while (node->left != NULL) node = node->left;
                node->left = temp;
                delete root;
                // return node1;
                return trimBST(node1, low, high);
            }
        } else {
            // root->left = trimBST(root->left, low, high);
            if (root->left) root->left = trimBST(root->left, low, high);
            // root->right = trimBST(root->right, low, high);
            if (root->right) root->right = trimBST(root->right, low, high);
        }   
        return root;  
    }

    bool juger(int num, int low, int high) {
        if (num > high) return false;
        if (num < low)  return false;
        return true;
    }
};

void trimLeftTrailingSpaces(string &input) {
    input.erase(input.begin(), find_if(input.begin(), input.end(), [](int ch) {
        return !isspace(ch);
    }));
}

void trimRightTrailingSpaces(string &input) {
    input.erase(find_if(input.rbegin(), input.rend(), [](int ch) {
        return !isspace(ch);
    }).base(), input.end());
}

TreeNode* stringToTreeNode(string input) {
    trimLeftTrailingSpaces(input);
    trimRightTrailingSpaces(input);
    input = input.substr(1, input.length() - 2);
    if (!input.size()) {
        return nullptr;
    }

    string item;
    stringstream ss;
    ss.str(input);

    getline(ss, item, ',');
    TreeNode* root = new TreeNode(stoi(item));
    queue<TreeNode*> nodeQueue;
    nodeQueue.push(root);

    while (true) {
        TreeNode* node = nodeQueue.front();
        nodeQueue.pop();

        if (!getline(ss, item, ',')) {
            break;
        }

        trimLeftTrailingSpaces(item);
        if (item != "null") {
            int leftNumber = stoi(item);
            node->left = new TreeNode(leftNumber);
            nodeQueue.push(node->left);
        }

        if (!getline(ss, item, ',')) {
            break;
        }

        trimLeftTrailingSpaces(item);
        if (item != "null") {
            int rightNumber = stoi(item);
            node->right = new TreeNode(rightNumber);
            nodeQueue.push(node->right);
        }
    }
    return root;
}

int stringToInteger(string input) {
    return stoi(input);
}

string treeNodeToString(TreeNode* root) {
    if (root == nullptr) {
      return "[]";
    }

    string output = "";
    queue<TreeNode*> q;
    q.push(root);
    while(!q.empty()) {
        TreeNode* node = q.front();
        q.pop();

        if (node == nullptr) {
          output += "null, ";
          continue;
        }

        output += to_string(node->val) + ", ";
        q.push(node->left);
        q.push(node->right);
    }
    return "[" + output.substr(0, output.length() - 2) + "]";
}

int main() {
    string line;
    while (getline(cin, line)) {
        TreeNode* root = stringToTreeNode(line);
        getline(cin, line);
        int low = stringToInteger(line);
        getline(cin, line);
        int high = stringToInteger(line);
        
        TreeNode* ret = Solution().trimBST(root, low, high);

        string out = treeNodeToString(ret);
        cout << out << endl;
    }
    return 0;
}
举报

相关推荐

0 条评论