C++ c++;可能的空指针取消引用

C++ c++;可能的空指针取消引用,c++,pointers,dereference,cppcheck,C++,Pointers,Dereference,Cppcheck,我检查了一些代码以查找可能的运行时错误。并且它正在报告可能的空指针取消引用,出现以下情况: Foo* x = ... //defined somewhere ... Foo* y(x); //possible null pointer dereference. 编辑:更好的例子 for( int i = 0; i < N; i++ ) { Foo* x( ArrayOfObjsContainingFooPtr[i].FooPtr ); // line 3 if( !x

我检查了一些代码以查找可能的运行时错误。并且它正在报告可能的空指针取消引用,出现以下情况:

Foo* x = ... //defined somewhere

...

Foo* y(x); //possible null pointer dereference.
编辑:更好的例子

for( int i = 0; i < N; i++ )
{
    Foo* x( ArrayOfObjsContainingFooPtr[i].FooPtr ); // line 3
    if( !x )                                         // line 4
        continue;
}
for(int i=0;i
来自cppcheck的错误消息:

 $ cppcheck --enable=all nullptrderef9.cpp 
 Checking nullptrderef9.cpp...
 [nullptrderef9.cpp:20] -> [nullptrderef9.cpp:22]: (warning) Possible null pointer dereference: x - otherwise it is redundant to check it against null.
 $ cppcheck --enable=all nullptrderef10.cpp 
 Checking nullptrderef10.cpp...
 [nullptrderef10.cpp:19]: (error) Possible null pointer dereference: p
[C:\file.cpp:3]:(错误)可能为空 指针取消引用:x-否则 是多余的,用于检查x在 第4行

但我不明白这是怎么可能的。

采取以下措施:

Foo* x = ptr_foo; //ptr_foo is defined earlier in the code.
但是如果
ptr_foo
是在程序的另一个点,在另一个文件中写入的呢?例如,假设您在
someotherfile.c
中发现:

ptr_null = 0;
那么完全有可能
Foo*x=ptr\u Fooy(x)
时,如果
y
取消引用
x
,则code>可能会导致错误的mojo

根据我的经验,静态分析工具往往会报告大量误报,因为它们没有关于程序的任何状态信息

如果真的想确保不会遇到空指针引用,可以尝试以下方法:

Foo* x = 0;
if(ptr_foo != 0){
    x = ptr_foo;
}else{
    x = //something else
}

我真的很惊讶你得到了那个警告。对我来说,情况正好相反。使用从Linux源代码编译的cppcheck 1.46.1。这很好:

struct Foo {
  int x;
};

struct Obj {
  Foo *FooPtr;
};

#define N 10

static Obj ArrayOfObjsContainingFooPtr[N];

int main() {
  for( int i = 0; i < N; i++ ) {
    Foo* x( ArrayOfObjsContainingFooPtr[i].FooPtr ); // line 3
    if( !x )                                         // line 4
      continue;
  }
}
int main() {
  Foo *p = 0;
  if (p->x == 0)
    return 1;
即使这是“好的”:

这最终会生成“可能的”空指针解引用。可能吧,对:

int main() {
  Foo *p = 0;
  p->x = 0;
有趣的是,虽然这与前面的示例完全相同,但它给出了明确的(不“可能”)空指针解引用:

int main() {
  Foo *p = 0;
  if ((*p).x == 0)
    return 1;

结论:cppcheck是一个非常有缺陷的工具。

只是对Sergey Tachenov的文章的总结:

 Foo* x( ArrayOfObjsContainingFooPtr[i].FooPtr ); // line 3
if (x->x == 0)
 break;
if( !x )                                         // line 4
 continue;
现在,cppcheck可以正确检测到这一点:

 $ cppcheck --enable=all nullptrderef9.cpp 
 Checking nullptrderef9.cpp...
 [nullptrderef9.cpp:20] -> [nullptrderef9.cpp:22]: (warning) Possible null pointer dereference: x - otherwise it is redundant to check it against null.
 $ cppcheck --enable=all nullptrderef10.cpp 
 Checking nullptrderef10.cpp...
 [nullptrderef10.cpp:19]: (error) Possible null pointer dereference: p
下一个示例也被正确检测到:

int main() {
  Foo *p = 0;
  if (p->x == 0)
  return 1;
}
以下是cppcheck的输出:

 $ cppcheck --enable=all nullptrderef9.cpp 
 Checking nullptrderef9.cpp...
 [nullptrderef9.cpp:20] -> [nullptrderef9.cpp:22]: (warning) Possible null pointer dereference: x - otherwise it is redundant to check it against null.
 $ cppcheck --enable=all nullptrderef10.cpp 
 Checking nullptrderef10.cpp...
 [nullptrderef10.cpp:19]: (error) Possible null pointer dereference: p
甚至下一个示例也演示了Cppcheck按预期工作:

 int main()
 {
    Foo *p = 0;
    if ((*p).x == 0)
       return 1;
 }
以下是输出:

$ cppcheck --enable=all nullptrderef11.cpp
  Checking nullptrderef11.cpp...
  [nullptrderef11.cpp:18]: (error) Possible null pointer dereference: p
  [nullptrderef11.cpp:18]: (error) Null pointer dereference

你能举一个更完整的例子吗?我怀疑存在导致这种情况的代码路径。请注意,静态代码分析工具并不完美,这可能是误报。这些示例都没有取消引用x。您的示例仍然不完整。你能发布最小的可编译代码吗?上面的代码可能导致空指针取消引用。代码示例的备用(IMHO cleaner)版本:
Foo*x=ptr\u Foo?ptr_foo:/*其他东西*不,从来没有“Foo*x=ptr_Foo;可能是坏魔咒”的可能性。这是指针副本,不是解引用。这就是我所想的Andrew@Andrew:如果“Foo*x=ptr\u-Foo;//其中ptr\u-Foo=0”,那么调用“y(x)//假设y解引用x”肯定是不好的方法。我发现我在回答中没有传达这一点,所以我更新了我的答案。+1:为了证明这个工具中的许多错误与问题高度相关,并且显然不难找到。