首页 > 解决方案 > Coverity——显式空解引用

问题描述

我有这样的场景:

int main() {
  int *p;
  int *q;
  bool cond1, cond2;

  // Does some processing and sets the cond1 and cond2

  if (cond1) {
     p = // Assign valid address
     q = NULL;
  } else {
     p = NULL;
     q = // Assign valid address
  }

  // Does something else but cond1 and cond2 remains untouched  

  if (cond2) {
    ***// Using 'q' data members.***
  }
}

我的代码中只有两个条件,cond1 和 cond2。首先 if 为 cond1 执行,else 为 cond2 执行。一次只能有一个为真。我看到粗体/斜体代码的覆盖缺陷。Coverity 抱怨以下消息:

CID 25469 (#1 of 1): Explicit null dereferenced (FORWARD_NULL)
9. var_deref_op: Dereferencing null pointer q.

我不明白为什么覆盖率在这里抱怨。在这种情况下,当我进入“cond2”时,我已经设置了“q”。正确的?我不明白的是什么?

我提出的解决方案:

.. 如果我这样写 !cond1 可以吗:

if (!cond1) {
  // Using 'q' data members.
}

..如果我添加额外的检查可以吗:

if (cond2 && q != NULL) {
  // Using 'q' data members.
}

.. 是误报吗?

还要别的吗?先感谢您。

标签: c++coverity

解决方案


从逻辑上讲,根据您所说的,并假设code1code2是互斥的,这是误报。但是,警告是有价值的,因为它指出[原文如此]从您的函数逻辑来看,安全性q并非显而易见。

我至少会放一个assert(q)inside if (code2),但是:

  1. 断言通常只在调试时应用(正如我最近被提醒的那样,发布版本中的运行时崩溃毫无意义——毕竟,我到处都有断言安全,对吧?)
  2. 可能仍然不足以满足 Coverity。

理想情况下,您会坚持使用那个if/else并将所有逻辑都放在那里。中间执行的通用逻辑?将其分离为您可以调用的不同函数。

这样做的额外好处是您可能不再需要两者pq因此整个功能变得更加精简。

但是,如果code1并且code2可能两者都是正确的,那么您确实有一个实质性的错误。


推荐阅读