首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 二叉搜索樹登錄系統:內存管理錯誤與遞歸調用棧溢出修復

     編輯:程式設計綜合問答

原代碼三大致命缺陷

  1. 棧上構建樹節點:`node a;` 為局部變量,函數返回後內存失效,指針懸空。必須 `new` 分配堆內存。
  2. 遞歸調用 `login()` 導致棧溢出:用戶名錯誤時 `login()` 直接遞歸,無基例終止,連續輸入錯誤即棧溢出。改用循環。
  3. 手動 `delete` 順序錯誤且重複釋放:`delete a.left->left` 後 `a.left->left = 0`,隨後 `delete a.left` 會二次釋放已釋放內存。應遞歸後序釋放。

修正版核心結構

class Node {
public:
    string name, keyword;
    Node *left, *right;
    Node(string n, string k) : name(n), keyword(k), left(nullptr), right(nullptr) {}
};

Node* buildTree() { // 堆上構建
    Node* root = new Node("f", "f");
    root->left = new Node("c", "c");
    root->left->left = new Node("123", "123");
    root->right = new Node("one", "one");
    root->right->right = new Node("wang", "@@110");
    return root;
}

void deleteTree(Node* root) { // 後序釋放
    if (!root) return;
    deleteTree(root->left);
    deleteTree(root->right);
    delete root;
}

bool search(Node* root, const string& name, const string& pwd) {
    while (root) {
        if (name < root->name) root = root->left;
        else if (name > root->name) root = root->right;
        else return root->keyword == pwd;
    }
    return false;
}

void login() {
    Node* root = buildTree();
    string user, pass;
    while (true) { // 循環代替遞歸
        cout << "用戶名 密碼: ";
        cin >> user >> pass;
        if (search(root, user, pass)) { cout << "登錄成功\n"; break; }
        // 此處可增加重試邏輯,區分用戶名/密碼錯誤
        cout << "失敗,重試\n";
    }
    deleteTree(root);
}

關鍵修復點總結

  • 所有樹節點 `new` 分配,統一 `deleteTree` 遞歸釋放。
  • 登錄邏輯改為 `while(true)` 循環,避免棧增長。
  • 查找函數返回 `bool` 簡化流程,移除引用參數。
  • 輸入使用 `cin >> user >> pass` 自動分割空白。< /li>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved