寫了一個「輸入 n 個數字建立鏈結串列,遍歷找出最小值節點」的 C 程式,邏輯看起來沒問題,但執行時要么直接 Segmentation Fault,要么印出一堆亂碼。重點錯誤在建立串列的迴圈與指標操作上。
head = (EXAMPLE*)malloc(sizeof(EXAMPLE));
pre = head;
for(i = 1; i <= n; i++) {
printf("input = ? ");
scanf("%d", &pre->input); // 寫入 pre 指向的節點
pre->keyword = i;
p = (EXAMPLE*)malloc(sizeof(EXAMPLE)); // 配置「下一個」節點
pre->next = p; // 串接
pre = p; // pre 移到新節點
}
pre = NULL; // ❌ 致命錯誤:只把區域變數 pre 設 NULL,串列尾巴沒斷開!
next 未設為 NULL:迴圈結束時,最後配置的節點 p 的 next 欄位是未初始化的垃圾值,非 NULL。後續 while(po) 遍歷不會在正確位置停下,導致存取非法記憶體 → 段錯誤。pre,再配置 p」,導致第 n 次迴圈配置的節點 完全沒被寫入資料,卻被串在串列尾端,遍歷時會印出亂碼。pre = NULL 完全無效:pre 只是區域指標變數,設為 NULL 不會影響串列結構,真正的尾節點 next 依然指向垃圾位址。head = (EXAMPLE*)malloc(sizeof(EXAMPLE));
if (!head) { printf("no memory\n"); return 0; }
printf("input = ? ");
scanf("%d", &head->input);
head->keyword = 1;
head->next = NULL; // ✅ 關鍵:明確終止
pre = head;
for (i = 2; i <= n; i++) { // 從 2 開始,head 已處理
p = (EXAMPLE*)malloc(sizeof(EXAMPLE));
if (!p) { printf("no memory\n"); return 0; }
printf("input = ? ");
scanf("%d", &p->input); // ✅ 直接寫入新節點 p
p->keyword = i;
p->next = NULL; // ✅ 每個新節點 next 歸零
pre->next = p; // 串接
pre = p; // 移動 pre
}
pMin = head;
p = head->next; // 從第二個節點開始比較
while (p) {
if (pMin->input > p->input)
pMin = p;
p = p->next;
}
printf("min : %d %d\n", pMin->keyword, pMin->input);
#include
#include
struct example {
int input;
int keyword;
struct example* next;
};
typedef struct example EXAMPLE;
int main(void) {
EXAMPLE *head, *p, *pre, *pMin;
int n, i = 1;
printf("n = ? ");
scanf("%d", &n);
if (n <= 0) return 0;
head = malloc(sizeof(EXAMPLE));
if (!head) { printf("no memory\n"); return 0; }
printf("input = ? ");
scanf("%d", &head->input);
head->keyword = i;
head->next = NULL;
i++;
pre = head;
for (; i <= n; i++) {
p = malloc(sizeof(EXAMPLE));
if (!p) { printf("no memory\n"); return 0; }
printf("input = ? ");
scanf("%d", &p->input);
p->keyword = i;
p->next = NULL;
pre->next = p;
pre = p;
}
// 列印驗證
for (p = head; p; p = p->next)
printf("%d %d\n", p->keyword, p->input);
// 找最小值
pMin = head;
for (p = head->next; p; p = p->next)
if (pMin->input > p->input) pMin = p;
printf("min : %d %d\n", pMin->keyword, pMin->input);
// 釋放記憶體(良好習慣)
for (p = head; p; ) {
EXAMPLE *tmp = p;
p = p->next;
free(tmp);
}
return 0;
}
指標操作最怕「以為串好了,其實尾巴沒斷」。每次 malloc 完馬上把 next 歸零,建立節點時直接寫入新節點而非舊節點,這兩個習慣能消滅 90% 的鏈結串列 Bug。下次寫鏈結串列,請在腦中預演:「配置 → 初始化 → 串接 → 移動」,一步不漏,程式就會穩如磐石。