cppcheck 空指针取消引用,但它实际上可以变为空

Posted

技术标签:

【中文标题】cppcheck 空指针取消引用,但它实际上可以变为空【英文标题】:cppcheck null pointer dereference, but it can actually become null 【发布时间】:2017-11-23 15:03:19 【问题描述】:

我有一个函数可以返回指向结构或 NULL 的指针(举例说明 get_my_struct_from_[X] 函数的返回可能性):

struct my_struct *my_function(my_struct i) 
    if (i.value < 5) return i;
    else return NULL;

在主程序中我多次调用此函数,然后检查值是否为 NULL:

struct my_struct *q;
q = get_my_struct_from_A();
if (q == NULL) 
    // display an error message and exit


q = get_my_struct_from_B();
if (q == NULL) 
    // display an error message and exit

CppCheck 告诉我 if 语句是多余的,或者可能存在空指针取消引用。

问题:

    为什么 CppCheck 会给我这些消息? 如何正确检查函数的返回值,以免收到此消息

编辑:

忘了提到 my_function 是两个 get 函数行为方式的示例。

get_my_struct_from_A 和 get_my_struct_from_B 内部逻辑不同,但输出数据类型与 my_function 中显示的相同。我有很多我调用并检查返回值的 get_my_struct_from_X 函数。因此,为每个 get 创建一个新结构不是一种选择,我认为这不是一个好选择,因为用于同一目的的大量变量。

q == null!q 从 cppcheck 返回相同的消息,我认为这是正常的。

【问题讨论】:

my_function 有问题:返回类型是struct my_struct *(一个指针)但是你返回一个inti)。 在使用 cppcheck 之前,您的代码会在没有警告的情况下编译。如果您没有收到警告,请使用 -Wall 进行编译 my_functionget_my_struct_from_A一样吗? 【参考方案1】:

你的函数应该返回struct my_struct *,当i.value小于5时你返回了什么? struct my_struct

另外,如果你像这样声明函数,你应该传递一个你没有传递的参数。

struct my_struct *my_function(struct my_struct* i) 
    if (i->value < 5) return i;
    else return NULL;

你会这样称呼它

struct my_struct a;
...
struct my_struct *q = my_function(&a);
if( !q )
   // it returned NULL


如果你展示的是你所做的,那么有问题/建议总结如下。

P 从方法中返回错误的类型。

P 如果get_my_struct_from_A 与原始代码中的my_function 相同,则说明您没有传递应传递的参数。

S 这种小检查可以通过使用一个根据传递的结构返回真或假的函数来更容易地完成。

bool my_function(struct my_struct ms);

【讨论】:

这里的主要问题是,在静态分析之前,这段代码首先如何能够干净地编译。 @Lundin.:是的,我猜 OP 没有发布确切的代码,或者 OP 在这里发布时更改了它。否则它会给我带来错误。这就是为什么我明确提到将使 OP 编写可编译代码的要点。 @coderredoc 我没有发布确切的代码,我不想要代码响应我想要解释我为什么会遇到这个问题。为问题添加了更多解释。【参考方案2】:
struct my_struct *my_function(my_struct i) 
    if (i.value < 5) return i;

这不是有效的 C(或 C++)代码。您的编译器损坏或配置不正确。

您返回一个整数,但该函数返回一个指针。 C标准明确,C11 6.8.6.4:

如果表达式有 类型与它出现的函数的返回类型不同,值为 就像通过赋值给具有函数返回类型的对象一样转换。

表示代码等价于struct my_struct* tmp = i;。这可以看作是C语言所说的“简单赋值”。简单赋值规则 C11 6.5.16.1 说如果赋值的左操作数是指针,那么右操作数不能是整数。

因此,您的编译器必须为此代码生成诊断消息。如果没有,那就有问题了。

【讨论】:

以上是关于cppcheck 空指针取消引用,但它实际上可以变为空的主要内容,如果未能解决你的问题,请参考以下文章

cppcheck 空指针取消引用:m_buffer - 否则检查它是不是为空是多余的

如何通过 Cppcheck 解释 Null 指针取消引用?

条件是多余的,或者可能存在空指针取消引用

C: Cppcheck : 可能的空点取消引用

在 sizeof 操作中取消引用空指针是不是有效[重复]

声明结构数组时,cppcheck 停止分析整个文件