錯誤代碼片段
int main() {
PQUEUE Q; // 定義指針變量,未初始化,值隨機
init(Q); // 傳遞指針的值(隨機地址),函數內修改的是副本
en_queue(Q,1); // 解引用野指針 → 崩潰
// ...
}
編譯器警告
warning C4700: 使用了未初始化的局部變量 "Q"
根因分析
PQUEUE 是 QUEUE* 類型別名。Q 是野指針。
init(Q) 按值傳遞指針,函數內對參數 pQ 賦值(malloc)只改變了副本,主函數的 Q 仍是野指針。
- 後續操作解引用野指針,觸發未定義行為(通常是段錯誤/訪問違例)。
兩種修正方法
方法一:傳遞指針的指針(雙重指針)
void init(PQUEUE *ppQ) { // 參數改為指針的指針
*ppQ = (PQUEUE)malloc(sizeof(QUEUE));
(*ppQ)->pBase = (int*)malloc(sizeof(int)*6);
(*ppQ)->front = 0;
(*ppQ)->rear = 0;
}
int main() {
PQUEUE Q = NULL; // 好習慣:初始化為 NULL
init(&Q); // 傳遞地址
// ...
}
方法二:函數返回分配好的指針(更簡潔)
PQUEUE init() {
PQUEUE pQ = (PQUEUE)malloc(sizeof(QUEUE));
pQ->pBase = (int*)malloc(sizeof(int)*6);
pQ->front = pQ->rear = 0;
return pQ;
}
int main() {
PQUEUE Q = init();
// ...
}
最佳實踐總結
- 指針聲明時立即初始化為 NULL。
- 需要在函數內修改指針本身(如分配內存)時,傳遞 指針的指針 或 返回新指針。
- 使用
malloc 後必須檢查返回值是否為 NULL。
- 釋放內存後將指針置 NULL,防止懸空指針二次釋放。