| 代碼 | 常數名稱 | 說明 | 原因分析與對策 |
| 200 | DivisionByZero | 除零錯誤 | 整數/浮點數除以 0。檢查除數是否為 0 |
| 201 | RangeCheckError | 範圍檢查錯誤 | 陣列越界、字串索引越界、賦值超出型別範圍。啟用 {$R+} 檢查 |
| 202 | StackOverflowError | 堆疊溢位 | 遞迴過深、區域變數過大、無限遞迴。增加堆疊或改用迴圈 |
| 203 | HeapOverflowError | 堆積溢位 | 記憶體不足、記憶體碎片化、大量物件未釋放 |
| 204 | InvalidPointer | 無效指標操作 | Free 零指標、雙重釋放、使用已釋放指標、指標運算錯誤 |
| 205 | FloatOverflow | 浮點數上溢 | 計算結果超出浮點數最大值 (如 1E300 * 1E300) |
| 206 | FloatUnderflow | 浮點數下溢 | 計算結果接近 0 超出精度範圍 |
| 207 | InvalidFloatOp | 無效浮點運算 | Sqrt(-1)、Log(0)、0/0、未初始化浮點變數 |
| 215 | ArithmeticOverflow | 算術溢位 | 整數運算超出型別範圍 (如 30000 * 30000 超過 SmallInt) |
| 216 | AccessViolation | 存取違規 (AV) | 讀/寫無效記憶體位址。最常見錯誤!見下文詳細分析 |
| 217 | ControlBreak | 控制中斷 | 用戶按 Ctrl+Break 或 Ctrl+C 終止主控台程式 |
| 218 | PrivilegedInstruction | 特權指令 | 嘗試執行 CPU 特權指令 (通常為編譯器/系統錯誤) |
| 219 | InvalidTypecast | 無效類型轉換 | as 轉換失敗、絕對地址轉換錯誤、介面查詢失敗 |
| 220 | InvalidVariantTypecast | 無效 Variant 轉換 | Variant 型別不相容轉換 (如字串轉 TDateTime 失敗) |
| 221 | InvalidVariantOp | 無效 Variant 運算 | Variant 不支援的運算子 (如字串相乘) |
| 222 | NoVariantDispatcher | 無 Variant 分派器 | 自定 Variant 類型缺少分派邏輯 |
| 223 | CannotCreateVariantArray | 無法建立 Variant 陣列 | VarArrayCreate 參數錯誤或記憶體不足 |
| 224 | VariantNotArray | Variant 不含陣列 | 對非陣列 Variant 使用陣列操作 |
| 225 | VariantArrayBounds | Variant 陣列邊界錯誤 | Variant 陣列索引越界 |
| 代碼 | 符號常數 | 說明 | Delphi 獲取方式 |
| 2 | ERROR_FILE_NOT_FOUND | 系統找不到指定檔案 | GetLastError / SysErrorMessage |
| 3 | ERROR_PATH_NOT_FOUND | 系統找不到指定路徑 | 同上 |
| 5 | ERROR_ACCESS_DENIED | 存取被拒絕 (權限不足) | 寫入受保護目錄、註冊表 |
| 6 | ERROR_INVALID_HANDLE | 無效控制代碼 | 關閉後再用 Handle |
| 8 | ERROR_NOT_ENOUGH_MEMORY | 記憶體不足 | 大量分配失敗 |
| 32 | ERROR_SHARING_VIOLATION | 檔案被佔用無法存取 | 獨佔開啟檔案時再次開啟 |
| 87 | ERROR_INVALID_PARAMETER | 參數錯誤 | API 傳參錯誤 |
| 112 | ERROR_DISK_FULL | 磁碟已滿 | 寫入失敗 |
| 123 | ERROR_INVALID_NAME | 檔名/路徑語法錯誤 | 路徑含非法字元 |
| 1450 | ERROR_NO_SYSTEM_RESOURCES | 系統資源不足 | GDI/USER 物件耗盡 |
| 1460 | ERROR_TIMEOUT | 逾時 | WaitForSingleObject 等 |
錯誤處理最佳實踐
1. 結構化異常處理 (try..except)
procedure SafeProcessFile(const FileName: string);
var
F: TextFile;
Line: string;
begin
AssignFile(F, FileName);
try
Reset(F);
try
while not Eof(F) do
begin
Readln(F, Line);
// 處理每行
end;
finally
CloseFile(F); // 確保關閉
end;
except
on E: EInOutError do
// I/O 錯誤 (代碼在 E.ErrorCode)
LogError(Format('I/O Error %d: %s', [E.ErrorCode, E.Message]));
on E: Exception do
// 其他異常
LogError(Format('Error: %s', [E.Message]));
end;
end;
2. 全域異常捕獲 (應用程式級)
// 在 .dpr 專案原始碼中
Application.OnException := GlobalExceptionHandler;
procedure GlobalExceptionHandler(Sender: TObject; E: Exception);
begin
// 記錄完整堆疊
LogException(E);
// 友善提示用戶
if E is EAccessViolation then
ShowMessage('程式發生內部錯誤 (存取違規),請重啟嘗試。')
else if E is EInOutError then
ShowMessage(Format('檔案操作失敗:%s', [E.Message]))
else
ShowMessage(Format('發生錯誤:%s', [E.Message]));
// 決定是否終止
// Application.Terminate;
end;
3. 取得詳細錯誤資訊的工具函數
function GetLastErrorMsg: string;
var
ErrCode: DWORD;
Buf: array[0..255] of Char;
begin
ErrCode := GetLastError;
if ErrCode = 0 then Exit('');
if FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, ErrCode, 0, Buf, 255, nil) > 0 then
Result := Format('OS Error %d: %s', [ErrCode, StrPas(Buf)])
else
Result := Format('OS Error %d (unknown)', [ErrCode]);
end;
// 使用範例
if not DeleteFile('test.txt') then
ShowMessage('刪除失敗:' + GetLastErrorMsg);
快速查詢索引
常見 I/O 錯誤
- 100: 讀取錯誤
- 101: 寫入錯誤
- 102: 檔案未指派
- 103: 檔案未開啟
- 104: 輸入檔未開啟
- 105: 輸出檔未開啟
- 106: 數值格式錯誤
常見致命錯誤
- 200: 除零
- 201: 範圍檢查
- 202: 堆疊溢位
- 203: 堆積溢位
- 204: 無效指標
- 205: 浮點上溢
- 206: 浮點下溢
- 207: 無效浮點運算
- 215: 算術溢位
- 216: 存取違規 ⭐
- 217: Ctrl+Break
- 219: 無效類型轉換
- 220: 無效 Variant 轉換
常見系統錯誤
- 2: 檔案不存在
- 3: 路徑不存在
- 5: 存取被拒絕
- 6: 無效控制代碼
- 32: 檔案共用違規
- 87: 參數錯誤
- 112: 磁碟已滿
- 123: 無效名稱
- 1450: 系統資源不足
總結
熟悉 Delphi 運行時錯誤代碼是快速定位 Bug 的關鍵技能。重點掌握:201 範圍檢查 (開啟 {$R+})、204 無效指標 (FastMM4 偵測)、216 存取違規 (最常見、最難查)、I/O 錯誤 100-106 (檔案操作基本功)。配合 GetLastError、SysErrorMessage、JclDebug/MadExcept 等工具,可將除錯效率提升數倍。
- 上一篇文章: DelphiX 圖片混合模式實戰:DrawAdd 與 DrawSub 加減色效果對比
- 下一篇文章: Delphi Database Desktop 主視窗完整介紹
Copyright ©
程式碼之家 All Rights Reserved