-1

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

成员 ids 包含一个数组。然后这个结构被赋予一个函数:

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

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

通过谷歌搜索,我在一个 linux 驱动程序中发现了一个类似的问题,该问题通过使用 memcpy 到堆栈变量来解决。但是,我根本不明白这个问题。内部数组的初始化器是否被视为范围限制器?有问题的文件可以在github上找到。

PS:arrayOfNodeIds的定义:

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

2 回答 2

3

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

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

于 2015-09-23T06:45:53.997 回答
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);

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

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

于 2015-09-23T06:54:16.817 回答