c++ - 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.
}
.. 是误报吗?
还要别的吗?先感谢您。
解决方案
从逻辑上讲,根据您所说的,并假设code1
和code2
是互斥的,这是误报。但是,警告是有价值的,因为它指出[原文如此]从您的函数逻辑来看,安全性q
并非显而易见。
我至少会放一个assert(q)
inside if (code2)
,但是:
- 断言通常只在调试时应用(正如我最近被提醒的那样,发布版本中的运行时崩溃毫无意义——毕竟,我到处都有断言安全,对吧?)
- 可能仍然不足以满足 Coverity。
理想情况下,您会坚持使用那个if
/else
并将所有逻辑都放在那里。中间执行的通用逻辑?将其分离为您可以调用的不同函数。
这样做的额外好处是您可能不再需要两者p
,q
因此整个功能变得更加精简。
但是,如果code1
并且code2
可能两者都是正确的,那么您确实有一个实质性的错误。
推荐阅读
- google-sheets - 分组时在谷歌查询中另一列最大时获取列值
- c# - C# asp.net core中现有类的JSON自定义序列化和反序列化
- java - 是否可以在这些代码上使用 JPanel 而不是 JComponent?
- javascript - 我如何找到两个 UNIX 时间之间的 HH:MM:SS 差异
- node.js - 如何使用@google-cloud/logging 发送带有文本消息和 JSON 有效负载的单个日志条目?
- linux - 相当于“树”命令但不是递归的?
- python - unittest 发现多个文件的模式
- php - 即使表格已填写,按钮仍处于禁用状态
- c# - EF 代码首先在我的模型中不存在的 DB 表上创建了一个列
- vb.net - Lucene.net visual basic.net