'指向本地外部范围'静态分析 - 假阳性?

时间:2015-09-23 06:31:33

标签: c c99 coverity

我有一个被Coverity标记的问题,我无法理解。

我有一个itializer:

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  };

成员ID拥有一个数组。然后这个结构被赋予一个函数:

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,它通过使用memcpy来解决堆栈变量。但是,我根本不明白这个问题。内部数组的初始值设定项是否被视为范围限制器?有问题的文件可以在github找到。

P.S。:arrayOfNodeIds的定义:

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

2 个答案:

答案 0 :(得分:3)

isd是一个指针,你可以指向复合文字。所有复合文字都被视为局部变量,它们具有局部范围。

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

答案 1 :(得分:1)

所以根据@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);

在这种情况下,struct和数组的范围是相同的。

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