Visual Studio中使用異常方法及開啟

來源:互聯網
上載者:User

  在使用Windows程式的時候,相信沒有使用者喜歡看到程式突然崩潰的情形吧!為了避免程式崩潰,程式員在編寫程式的時候最好在容易出錯的地方使用異常處理機制來保證友好的使用者體驗。特別是編寫C/C++代碼的時候,崩潰是經常的事情!
  今天一位同事給我說,編寫C/C++代碼崩潰的原因主要是因為記憶體操作違規。如果每次操作一塊記憶體或指標之前都檢查記憶體或指標是否有效,那麼可以降低程式崩潰的次數。但是這會讓程式員很厭煩的,哈哈。所以在適當的地方加上異常處理,即使崩潰也會讓程式員更好的改善程式。當然,程式效率必然降低! 

  幸好C++規範中有異常處理機制: try catch

  但是在Visual Studio中直接使用try catch是不能產生異常的,必須手動拋出異常throw,見如下代碼:

void TryCatchfourth()
{
char* Test = NULL;
try
{
Test = new char[2];
FreeArray(Test);
throw 0; // 這裡我是隨便拋出異常以測試
// 若沒有手動throw,後面即使產生異常catch裡面的代碼還是不會被執行
puts("No "); // 接下來這兩句不會被執行
*(Test + 4096 ) = '\0';
}
catch (...)
{
if (NULL != Test)
{
FreeArray(Test);
}
printf("4 \n");
}
puts("Fourth");
}

  又下面這段代碼,如果將vs編譯器的選項修改:開啟項目屬性→配置屬性→C/C++→代碼產生→啟用C++異常→是,但有SEH異常(/EHa) (這裡編譯器預設為"是(/EHsc)")。

void TryCatchThree()
{
char* Test = NULL;
try
{
Test = new char[2];
FreeArray(Test);
*(Test + 4096 ) = '\0';
}
catch (...)
{
if (NULL != Test)
{
FreeArray(Test);
}
printf("4 \n");
}
puts("Three");
}

  修改編譯器選項之後執行TryCatchThree()就正常工作。請注意TryCatchThree()和TryCatchfourth()所採用的不同編譯選項。

  最後參考一個Windows的結構化異常處理代碼:

void TryCatchSecond()
{
char* Test = NULL;
__try
{
__try
{
Test = new char[2];
FreeArray(Test);
*(Test + 4096 ) = '\0';
// 此處數字一定要大,否則不能產生異常。
// 因為Windows平台下,new N個位元組,系統分配的一定比N大。
// 4096大小剛好是一個頁面大小,如果N>4096,那就自己擴大對應數字以產生異常
}
__finally
{
if (NULL != Test)
{
FreeArray(Test);
}
printf("2 "); // this is printed second
}
}
__except ( FilterFunction(GetExceptionCode()) )
{
printf("3 \n"); // this is printed last
}
puts("Second");
}

  不管編譯器選項是否按照上述要求被修改,TryCatchSecond()均能正常工作。同事說,這是Windows結構化異常,和C++中的異常有點不一樣,我現在也不太懂,以後查到資料後在添加到部落格中來。TryCatchSecond()代碼是參考MSDN中的一個例子,如下:

DWORD FilterFunction(int i = 1) 
{
printf("%d ", i); // printed first
return EXCEPTION_EXECUTE_HANDLER;
}

void TryCatchFirst()
{
char* Test = NULL;
__try
{
__try
{

// 這個API是手動設定異常代碼(這麼稱呼有點彆扭)
RaiseException(1, // exception code
0, // continuable exception
0, NULL); // no arguments
}
__finally
{
printf("2 "); // this is printed second
}
}
__except ( FilterFunction() )
{
printf("3 \n"); // this is printed last
}
puts("One");
}

  下面是完整代碼:(本文中代碼均在vs2008中編寫和測試,建議不要在vc6下測試,vc6對C++規範支援很不好

View Code

#include <windows.h>

// 釋放數組記憶體
#define FreeArray(pArray) { \
delete[] pArray; \
pArray = NULL; \
}
DWORD FilterFunction(int i = 1)
{
printf("%d ", i); // printed first
return EXCEPTION_EXECUTE_HANDLER;
}

void TryCatchFirst()
{
char* Test = NULL;
__try
{
__try
{

// 這個API是手動設定異常代碼(這麼稱呼有點彆扭)
RaiseException(1, // exception code
0, // continuable exception
0, NULL); // no arguments
}
__finally
{
printf("2 "); // this is printed second
}
}
__except ( FilterFunction() )
{
printf("3 \n"); // this is printed last
}
puts("One");
}

void TryCatchSecond()
{
char* Test = NULL;
__try
{
__try
{
Test = new char[2];
FreeArray(Test);
*(Test + 4096 ) = '\0';
// 此處數字一定要大,否則不能產生異常。
// 因為Windows平台下,new N個位元組,系統分配的一定比N大。
// 4096大小剛好是一個頁面大小,如果N>4096,那就自己擴大對應數字以產生異常
}
__finally
{
if (NULL != Test)
{
FreeArray(Test);
}
printf("2 "); // this is printed second
}
}
__except ( FilterFunction(GetExceptionCode()) )
{
printf("3 \n"); // this is printed last
}
puts("Second");
}
void TryCatchThree()
{
char* Test = NULL;
try
{
Test = new char[2];
FreeArray(Test);
*(Test + 4096 ) = '\0';
}
catch (...)
{
if (NULL != Test)
{
FreeArray(Test);
}
printf("4 \n");
}
puts("Three");
}
void TryCatchfourth()
{
char* Test = NULL;
try
{
Test = new char[2];
FreeArray(Test);
throw 0; // 這裡我是隨便拋出異常以測試
// 若沒有手動throw,後面即使產生異常catch裡面的代碼還是不會被執行
puts("No "); // 接下來這兩句不會被執行
*(Test + 4096 ) = '\0';
}
catch (...)
{
if (NULL != Test)
{
FreeArray(Test);
}
printf("4 \n");
}
puts("Fourth");
}

VOID main(VOID)
{
// TryCatchFirst();
// TryCatchSecond();
// TryCatchThree();
// TryCatchfourth();
}

 

【參考資料 感謝作者】
1、我的同事 

   

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.