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