執行修改或刪除操作後,呼叫 allselect() 輸出全部資料時,開頭出現學號 -842150451、姓名 屯屯屯屯屯屯、籍貫 屯屯屯屯屯屯 的垃圾資料,每操作一次多一筆。
鏈結串列節點刪除/修改邏輯錯誤,導致未正確釋放記憶體或指標斷裂,殘留未初始化的記憶體區塊被誤讀。 具體常見錯誤:
jgdelete 刪除節點後,未將前一節點的 next 指向被刪節點的 next,造成鏈斷,遍歷時跑到野指標區域。jgedit 修改時誤用 malloc 建立新節點卻未插入鏈表,舊節點未釋放。TotalSco、AveSco 等欄位含隨機值 (如 0xCCCCCCCC 解釋為 -842150451)。Node* prev = find_prev(head, target_id);
if (prev && prev->next) {
Node* del = prev->next;
prev->next = del->next;
free(del);
}
malloc。memset(&node, 0, sizeof(Node)) 或逐欄位賦值。
void allselect(Node* head) {
Node* p = head;
while (p) {
if (p->id > 0) { // 簡易過濾垃圾資料
printf("%d %s %s\n", p->id, p->name, p->native);
}
p = p->next;
}
}
// 刪除
void jgdelete(Node** head, int id) {
Node *cur = *head, *prev = NULL;
while (cur && cur->id != id) { prev = cur; cur = cur->next; }
if (!cur) return; // 找不到
if (prev) prev->next = cur->next;
else *head = cur->next;
free(cur);
}
// 修改
void jgedit(Node* head, int id) {
Node* cur = head;
while (cur && cur->id != id) cur = cur->next;
if (!cur) return;
printf("請輸入新姓名 籍貫: ");
scanf("%s %s", cur->name, cur->native);
}
valgrind --leak-check=full 偵測記憶體洩漏/非法存取。allselect 中印出節點位址 %p,觀察是否出現重複/異常位址。std::vector (C++) 簡化管理,除非教學要求鏈結串列。