「640K ought to be enough for everybody」—— Bill Gates, 1981
程式設計師常在提心吊膽中撰寫記憶體管理程式碼。不想踩雷,唯有**發現所有潛在地雷並排除**,躲是躲不掉的。本章深度遠超一般教科書,請細讀,做到真正通曉記憶體管理。
static 變數。malloc/new 申請任意大小,程式設計師負責用 free/delete 釋放。生存期由我們決定,彈性最大,**問題也最多**。記憶體錯誤極麻煩:編譯器無法自動發現,通常執行期才暴露;多無明顯症狀,時隱時現,難以重現除錯。
| 錯誤類型 | 成因 | 對策 |
|---|---|---|
| 配置失敗卻使用 | 新手未意識到配置可能失敗 | 使用前檢查指標是否 NULL;參數用 assert(p!=NULL);malloc/new 用 if(p==NULL) |
| 配置成功但未初始化就引用 | 無初始化觀念;誤以為預設為零 | 無論何種方式建立陣列,**別忘了賦初值**,即便是零值也不可省略 |
| 操作超出記憶體邊界 | 陣列下標「多1」或「少1」;for 迴圈次數易搞錯 | 嚴防下標越界,特別當心「多1/少1」操作 |
| 忘記釋放 → 記憶體洩漏 | 每調用一次丟失一塊記憶體,延遲爆發 | 動態記憶體申請與釋放必須配對,malloc/free 次數必相同(new/delete 同理) |
| 釋放後繼續使用 | 1.物件關係複雜難判斷 2.return 回傳堆疊指標 3.free/delete 後未置 NULL | 1.重新設計資料結構 2.勿回傳堆疊指標/參考 3.釋放後**立即置 NULL** |
malloc/new 後立即檢查指標是否 NULL。free/delete 後立即將指標設為 NULL,防野指標。兩者在許多場合可互換,易產生等價錯覺。
下文以字串為例詳細比較兩者特性。