我有一个被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;
答案 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和数组的范围是相同的。
另一种方法是在堆上分配内存,而不是去堆栈。