指針是 C 語言最強大也最危隐的特性。本文歸納六大類高發錯誤場景,提供代碼反例與防禦模式,助你構建記憶體安全的程式。
#define PINT int* PINT ptr1, ptr2; // 實為 int* ptr1, ptr2; ptr2 是 int 而非指針!
修正:用 typedef int* PINT;,則 PINT ptr1, ptr2; 皆為指針。
區域指針未賦值指向隨機地址,解參考導致未定義行為。
int *p = NULL;assert(p != NULL); 捕獲空指針解參考。gets()、strcpy()、strcat() 等不安全函數// 安全版字串複製
void safe_copy(char *dest, size_t dest_size, const char *src) {
size_t len = strlen(src);
if (len >= dest_size) len = dest_size - 1;
memcpy(dest, src, len);
dest[len] = '\0';
}
int *p = malloc(n * sizeof(int));
if (!p) { /* 處理失敗 */ return; }
free(p) 後繼續使用 p,指向已釋放記憶體。
free(p); p = NULL;memset(p, 0, size); free(p);對同一指針多次 free() 導致堆破壞。置空策略可有效預防。
void func(int arr[]) { // 實為 int* arr
printf("%zu\n", sizeof(arr)); // 輸出指針大小(4/8),非陣列大小!
}
對策:陣列作參數時,必須同步傳遞長度。
\0 空間。
NULLmalloc 必檢查返回值strncpy/snprintf 替代不安全函數-Wall -Wextra)與 sanitizers指針錯誤多屬「海森堡 Bug」——難以復現、後果嚴重。建立防禦性編程習慣,善用工具鏈,是 C 開發者的必修課。