參考網址: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();
....
}
….