简体   繁体   English

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

[英]Pointer to local variable is stored outside the scope of this variable

For the following code snippet, which is a part of libgearman 对于以下代码段,这是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 reported: 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;
    }
------------

Regarding the question Pointer to local variable outside the scope of its declaration , if I understand that correctly, malloc and free should be used for refactoring. 关于指向声明其范围之外的局部变量的问题,如果我理解正确,则应使用mallocfree进行重构。 My question is if there is an other appropriate refactoring alternative. 我的问题是是否还有其他适当的重构方法。 For instance using of std::unique_ptr : 例如使用std :: unique_ptr

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

The ret_ptr parameter to the function in question is expected to point to a variable in the calling function. 该函数的ret_ptr参数应指向调用函数中的变量。 This pointer is then dereferenced for both reading and writing this external variable. 然后,为读取和写入此外部变量而取消引用该指针。

The if (ret_ptr == NULL) block checks whether the caller actually passed in the address of some variable. if (ret_ptr == NULL)块检查调用方是否实际传递了某个变量的地址。 If not, this pointer is then made to point to the local variable unused so that the pointer can still be safely dereferenced later in the code. 如果不是,则使该指针指向unused的局部变量,以便以后仍可以在代码中安全地取消引用该指针。 But since ret_ptr now points to a local, changes made by dereferencing it are not seen outside the function. 但是由于ret_ptr现在指向本地,因此在函数外部看不到通过取消引用该本地所做的更改。 This is fine, since the caller passed in NULL for ret_ptr . 这很好,因为调用方为ret_ptr传递了NULL Similarly, since ret_ptr is a parameter, any changes to it are not visible outside of the function. 同样,由于ret_ptr是一个参数,因此对其进行的任何更改在函数外部均不可见。

Nothing needs to be refactored here. 这里不需要重构。 The code works as intended with regard to ret_ptr . 该代码按照ret_ptr预期工作。 This is a false positive from PVS-Studio. 这是来自PVS-Studio的误报。

EDIT: 编辑:

This is NOT a false positive. 不是误报。 The unused variable is defined at a lower scope than ret_ptr , namely the scope of the first if block in the function. unused变量的定义范围小于ret_ptr的范围,即函数中第一个if块的范围。 After the if block, ret_ptr is then dereferenced. if块之后, ret_ptr被取消引用。 If it was pointing to ununsed , that variable is now out of scope and dereferencing ret_ptr invokes undefined behavior . 如果它指向ununsed ,则该变量现在超出范围,取消引用ret_ptr调用未定义的行为

To fix this, unused must be declared and assigned to above the if block: 要解决此问题,必须声明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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM