VS2005之后的版本,微軟增加了一些新的異常機制,新機制在出現錯誤時默認不通知應用程序,這時程序就崩潰了。所以這種情況下,必須調用_set_invalid_parameter_handler、_set_purecall_handler設置自己的異常處理函數。以下示例代碼:
// test.cpp
// compile with: /Zi /MTd
// C++ Exceptions : /EHa
#include <stdio.h>
#include <stdlib.h>
void myInvalidParameterHandler(const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
// function、file、line在Release下無效
wprintf(L"Invalid parameter detected in function %s."
L" File: %s Line: %d\n", function, file, line);
wprintf(L"Expression: %s\n", expression);
// 必須拋出異常,否則無法定位錯誤位置
throw 1;
}
void myPurecallHandler(void)
{
printf("In _purecall_handler.");
// 必須拋出異常,否則無法定位錯誤位置
throw 1;
}
int main()
{
char* formatString;
_invalid_parameter_handler oldHandler;
_purecall_handler old_pure_handle;
oldHandler = _set_invalid_parameter_handler(myInvalidParameterHandler);
old_pure_handle = _set_purecall_handler(myPurecallHandler);
try
{
formatString = NULL;
printf(formatString); // 發生異常
}
catch(...)
{
// 定位錯誤位置,輸出log
printf("catch");
}
getchar();
}
說明:
1、由于formatString是空指針,printf(formatString)發生異常,這時CRT會調用myInvalidParameterHandler進行處理;
2、myInvalidParameterHandler拋出異常。注意,function、file、line在Release下無效,所以必須拋出異常,否則無法定位錯誤代碼;
3、設置工程選項C++ Exceptions : /EHa,讓catch抓住myInvalidParameterHandler拋出的異常,再做相應的處理;
注意:如果myInvalidParameterHandler不拋出異常,那程序會往下執行,那么可能會發生更糟糕的情況。因此,建議拋出異常,中止執行后續的代碼。