'Pointer to local outside scope' 通过静态分析 -- 误报?

'Pointer to local outside scope' by static analyzis -- false positive?

我遇到了 Coverity 标记的一个我无法理解的问题。

我有一个初始化器:

1686  arrayOfNodeIds componentRefs = (arrayOfNodeIds) {
1687    .size = 2,
1688    .ids  = (UA_NodeId[]) { UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY)}
1689  };

member ids 持有一个数组。然后这个结构被赋予一个函数:

1707  UA_Server_addInstanceOf_instatiateChildNode(server, &subtypeRefs, &componentRefs, &typedefRefs,
1708                                              objectRoot, callback, (UA_ObjectTypeNode *) typeDefNode, 
1709                                              UA_TRUE, &instantiatedTypes, handle);

该函数取消引用 conponentRefs->ids 并且 Coverity 将其标记为对范围外的局部变量的访问。

通过谷歌搜索,我发现了一个类似的 issue in one linux driver that was solved by using a memcpy to a stack variable. However, I do not understand the problem at all. Is the initializer of the internal array considered as a scope limiter? The problematic file can be found on github

P.S.: arrayOfNodeIds 的定义:

typedef struct arrayOfNodeIds_s {
  UA_Int32  size;
  UA_NodeId *ids;
} arrayOfNodeIds;

isd 是一个指针,你让它指向一个复合文字。所有复合文字都被视为局部变量,它们具有局部作用域。

因此,如果您的结构是静态存储持续时间(不太清楚您对 "static itializer" 的意思),那么该工具是正确的抱怨。因为在那种情况下,一旦程序离开你初始化 isd 的范围,它就会指向垃圾。您必须指向另一个静态存储持续时间变量或使用动态分配。

所以根据@Lundin 的回答,这可能有助于解决问题

  UA_NodeId* tempArray = (UA_NodeId[]) { UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION)};
  arrayOfNodeIds typedefRefs = (arrayOfNodeIds) {
    .size = 1,
    .ids  = tempArray
  };
  UA_Server_addInstanceOf_instatiateChildNode(server, &subtypeRefs, &componentRefs, &typedefRefs,
                                                objectRoot, callback, (UA_ObjectTypeNode *) typeDefNode, 
                                                UA_TRUE, &instantiatedTypes, handle);

在这种情况下,结构和数组的作用域是相同的。

另一种方法是在堆上分配内存,而不是去堆栈。