指向局部变量的指针存储在此变量的范围之外

时间:2017-05-31 13:04:51

标签: c++ c

对于以下代码段,它是libgearman

的一部分
gearman_job_st *gearman_worker_grab_job(gearman_worker_st *worker_shell,
                                        gearman_job_st *job,
                                        gearman_return_t *ret_ptr)
{
    if (worker_shell and worker_shell->impl())
    {

        ...

        gearman_return_t unused;
        if (ret_ptr == NULL)
        {
            ret_ptr= &unused;
        }
        ...
    }

    assert(*ret_ptr != GEARMAN_MAX_RETURN);
    return NULL;
}

PVS-Studio报道:

Viva64-EM
full
671
/nfs/home/xxx/src/gearmand/libgearman/worker.cc
error
V506
Pointer to local variable 'unused' is stored outside the scope of this variable. Such a pointer will become invalid.
false
2
    {
      ret_ptr= &unused;
    }
------------

关于问题Pointer to local variable outside the scope of its declaration,如果我理解正确,mallocfree应该用于重构。我的问题是,是否有其他适当的重构替代方案。例如使用std::unique_ptr

ret_ptr = std::make_unique<gearman_return_t>();

1 个答案:

答案 0 :(得分:8)

有问题的函数的ret_ptr参数应指向调用函数中的变量。然后取消引用该指针以读取和写入该外部变量。

if (ret_ptr == NULL)块检查调用者是否实际传入了某个变量的地址。如果没有,则使该指针指向局部变量unused,以便稍后在代码中仍然可以安全地取消引用指针。但由于ret_ptr现在指向本地,因此在函数外部看不到通过解除引用而进行的更改。这很好,因为来电者NULL传递了ret_ptr。同样,由于ret_ptr是一个参数,因此对它的任何更改都不会在函数外部显示。

这里没有什么需要重构的。代码按照ret_ptr的方式工作。这是PVS-Studio的误报。

编辑:

这是误报。 unused变量的定义范围低于ret_ptr,即函数中第一个if块的范围。在if阻止之后,ret_ptr被解除引用。如果它指向ununsed,则该变量现在已超出范围,并且取消引用ret_ptr会调用undefined behavior

要解决此问题,必须声明unused并将其分配到if块之上:

gearman_job_st *gearman_worker_grab_job(gearman_worker_st *worker_shell,
                                        gearman_job_st *job,
                                        gearman_return_t *ret_ptr)
{
    gearman_return_t unused;
    if (ret_ptr == NULL)
    {
        ret_ptr= &unused;
    }

    if (worker_shell and worker_shell->impl())
    {
        ...
    }

    assert(*ret_ptr != GEARMAN_MAX_RETURN);
    return NULL;
}