程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> PVS-Studio V668警告

PVS-Studio V668警告

編輯:C++入門知識

PVS-Studio V668警告


參考網址:http://www.viva64.com/en/d/

http://www.viva64.com/en/pvs-studio/

警告說明

V668. There is no sense in testing thepointer against null, as the memory was allocated using the 'new' operator. Theexception will be generated in the case of memory allocation error

當由new操作返回的指針值與NULL比較時,PVS-Studio分析器已經檢測到一個問題。它通常意味著:如果內存不能被分配,程序將出現一種意想不到的方式。

如果new操作分配內存失敗,根據C++標准程序會拋出std::bad_alloc()異常。因此,檢查指針為空是毫無意義的。看下面這個簡單例子:

MyStatus Foo()

{

int*p = new int[100];

if(!p)

return ERROR_ALLOCATE;

...

return OK;

}

P指針將從來不會等於0,函數將從來不會返回常量值ERROR_ALLOCATE。如果內存不能分配,將會產生一個異常。我們可以選擇一種最簡單的方式修改代碼。

MyStatus Foo()

{

try

{

int *p = new int[100];

...

}

catch(const std::bad_alloc &)

{

return ERROR_ALLOCATE;

}

return OK;

}

然而,注意上面顯示的修復代碼非常差。異常處理是完全不同的哲理:因為他們讓我們避免很多檢查和返回狀態的異常。我們應該讓異常從Foo函數拋出,在更高層的地方處理它。不幸的是,討論如何使用異常已經超出本文檔的范圍。

讓我們看看現實生活中這樣一個錯誤看起來是什麼樣的,下面是從真實應用中或取得代碼片段:

// For each processor; spawn a CPU threadto access details.

hThread = new HANDLE [nProcessors];

dwThreadID = new DWORD [nProcessors];

ThreadInfo = new PTHREADINFO [nProcessors];

// Check to see if the memory allocationhappenned.

if ((hThread == NULL) ||

(dwThreadID == NULL) ||

(ThreadInfo == NULL))

{

char * szMessage = new char [128];

sprintf(szMessage,

"Cannot allocate memory for "

"threads and CPU information structures!");

MessageBox(hDlg, szMessage, APP_TITLE, MB_OK|MB_ICONSTOP);

delete szMessage;

return false;

}

使用者將從來不會看到錯誤消息的窗口。如果內存不能分配,程序將崩潰或者產生一個不合適的消息,在一些其它地方處理異常。

這種問題的常見原因是修改new操作的行為。在Visual C++ 6.0時代,new操作會返回NULL以防止錯誤。後來Visual C++版本跟隨標准產生一個異常。記住這種行為的變化。因此,如果你采用老的項目使用現代編譯器編譯它,你應該特別關注下V668診斷。

注N1:分析器不會生成一個警告,如果使用 placement new或“new (std::nothrow)。例如:

T * p = new (std::nothrow) T; // OK

if (!p) {

//An error has occurred.

//No storage has been allocated and no object constructed.

...

}

注N2:你可以使用nothrownew.obj連接項目,這種情況下new操作不會拋出異常。例如:驅動開發者,應用這個功能。更多詳情參考MSDN的new和delete操作http://msdn.microsoft.com/en-us/library/kftdy56f%28v=vs.110%29.aspx。這種情況下只要關閉掉V668警告。

更多示例

NextXMS:

PRectangle CallTip::CallTipStart(....)

{

....

val= new char[strlen(defn) + 1];

if(!val)

return PRectangle();

....

}

….

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved