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

C 語言鏈表刪除節點後繼續遍歷導致 Runtime Error:free 後不可再訪問指標

     編輯:程式設計疑難解答

錯誤代碼片段

void DeleteLink(List *L, int n) {
    List *p = L->next;
    List *s = L;
    for (int i = 0; p != NULL; i++) {
        if (i == n) {
            s->next = p->next;
            free(p);           // 釋放節點
        }
        s = s->next;           // 錯誤:p 已 free,s->next 可能指向已釋放記憶體
        p = p->next;           // 錯誤:p 已 free,訪問 p->next 未定義行為
    }
}

問題分析

`free(p)` 後,`p` 成為**懸空指標**。後續 `s = s->next`、`p = p->next` 皆訪問已釋放記憶體,導致未定義行為,OJ 判為 Runtime Error。

正確刪除邏輯

void DeleteLink(List *L, int n) {
    List *p = L->next;
    List *s = L;
    for (int i = 0; p != NULL; i++) {
        if (i == n) {
            s->next = p->next; // 先斷鏈
            free(p);           // 再釋放
            return;            // 刪除單節點後直接返回,避免後續訪問
        }
        s = p;                 // 正常推進:s 跟隨 p
        p = p->next;
    }
}

關鍵點

  1. **先斷鏈,再釋放**:`s->next = p->next` 保證鏈表連續性。
  2. **釋放後立即返回/跳出迴圈**:不要繼續使用 `p` 或 `s->next`(若 `s` 指向被刪節點)。
  3. 若需刪除多個節點,在迴圈中記錄 `next = p->next` 再 `free(p)`,最後 `p = next`。

題目完整解法提示

題目要求刪除鏈表 A 中同時存在於 B 和 C 的元素。三表有序,可用**三指標同步遍歷**(類似歸併),時間複雜度 O(m+n+l),避免重複查找導致 O(m*(n+l)) 超時。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved