精選高頻面試題,從標準庫陷阱到底層內存模型,附標準答案與最佳實踐指導。
| # | 主題 | 核心考點 | 關鍵詞 |
|---|---|---|---|
| 1 | gets() 緩衝區溢出 | 不安全函數棄用 | fgets 替代 |
| 2 | strcpy() 覆蓋返回地址 | 棧溢出攻擊原理 | strncpy 防護 |
| 3 | main() 返回類型 | 規範簽名 int main() | 腳本協作 |
| 4 | 內存洩漏生命周期 | 程序結束自動回收 vs 循環洩漏 | Valgrind |
| 5 | free() 指針修改陷阱 | 指針算術改變基址 | 保存原始指針 |
| 6 | _exit() vs exit() | 清理處理程序調用差異 | atexit |
| 7 | void* 通用接口 | 類型擦除與結構體封裝 | 泛型編程 |
| 8 | *ptr++ 優先級 | 後綴++ 綁定緊於 * | *(ptr++) |
| 9 | 修改字符串字面量 | 只讀段寫入導致 SIGSEGV | 字面量存儲區 |
| 10 | 修改 argv[0] 進程名 | 運行時進程元數據修改 | ps/top 顯示 |
| 11 | 返回局部變量地址 | 棧幀失效導致懸空指針 | 輸出參數模式 |
| 12 | printf 參數求值順序 | 右向左求值,左向右輸出 | 調用約定 |
char passwd[10];
strcpy(passwd, argv[1]); // 無長度檢查
// 輸入超長字符串覆蓋相鄰 flag 變量
// 即使密碼錯誤,flag 非零繞過驗證
防護:strncpy、編譯器 -fstack-protector、地址隨機化 ASLR。
char *ptr = malloc(10);
while (*ptr != 'z') ptr++; // ptr 移動
free(ptr); // 傳遞非原始地址 -> 未定義行為
修正:保存 char *orig = ptr; 用於 free。
char *ptr = "Linux";
printf("%c", *ptr++); // 輸出 'L',ptr 移向 'i'
printf("%c", *ptr); // 輸出 'i'
規則:後綴 ++ 優先級高於 *,結合方向左到右。
int* inc(int val) {
int a = val; a++;
return &a; // 返回棧上地址
}
// 調用者使用時棧幀已銷毀
修正:傳入輸出參數 void inc(int val, int *out)。
int a=10,b=20,c=30;
printf("%d..%d..%d", a+b+c, (b=b*2), (c=c*2));
// 求值順序:右到左 -> c=60, b=40, sum=110
// 輸出順序:左到右 -> 110..40..60
這 12 題覆蓋 C 語言核心難點 80%,吃透即通關系統編程面試核心關。