我有一个包含动态结构数组的结构:
struct C_Node {
int id;
int num_children;
int* children;
};
struct C_Transition {
int id;
int duration;
int num_parents;
int num_children;
int* parents;
int* children;
};
struct C_PetriNet {
int num_nodes;
int num_transitions;
C_Node* nodes;
C_Transition* transitions;
};
我想初始化并返回外部结构,如下所示:
C_PetriNet* Cpp_C_interface::convert_PetriNet(PetriNet petriNet) {
int num_nodes = static_cast<int>(petriNet.nodes.size());
int num_transitions = static_cast<int>(petriNet.transitions.size());
C_PetriNet* c_petriNet = (C_PetriNet*)malloc(sizeof(C_PetriNet));
C_Node* c_nodes = new C_Node[num_nodes];
C_Transition* c_transitions = new C_Transition[num_transitions];
for (int i = 0; i < num_nodes; i++) {
c_nodes[i].id = petriNet.nodes[i].id;
c_nodes[i].num_children = petriNet.nodes[i].childs.size();
c_nodes[i].children = petriNet.nodes[i].childs.data();
}
for (int i = 0; i < num_transitions; i++) {
c_transitions[i].id = petriNet.transitions[i].id;
c_transitions[i].duration = petriNet.transitions[i].duration;
c_transitions[i].num_parents = petriNet.transitions[i].parents.size();
c_transitions[i].num_children = petriNet.transitions[i].childs.size();
c_transitions[i].children = petriNet.transitions[i].childs.data();
c_transitions[i].parents = petriNet.transitions[i].parents.data();
}
c_petriNet->num_nodes = num_nodes;
c_petriNet->num_transitions = num_transitions;
c_petriNet->nodes = c_nodes;
c_petriNet->transitions = c_transitions;
return c_petriNet;
};
并在主要使用它:
C_PetriNet* c_petriNet;
c_petriNet = Cpp_C_interface::convert_PetriNet(petriNet);
std::cout << "Test out: " << c_petriNet->num_nodes << std::endl;
std::cout << "Test out: " << c_petriNet->nodes[5].children[8] << std::endl;
std::cout << "Test out: " << c_petriNet->transitions[68].parents[1] << std::endl;
但是,只有第一个输出(num_nodes)是正确的。如果我在返回之前在函数内打印,一切正常。我还能做什么来返回动态分配的内存?
答案 0 :(得分:1)
问题是petriNet
是传递给您的函数的对象的本地副本。您正在保存指向您正在创建的新data()
和petriNet
中的C_Node
中各种向量的C_Transition
的指针,但这些指针在函数返回时变为无效
如果更改函数以获取引用,只要调用者的对象处于活动状态,指针就会保持有效,但仍然很脆弱。你真正需要做的是复制所有数据。所以你可以使用memcpy()
:
memcpy(c_nodes[i].children, petriNet.nodes[i].childs.data(), c_nodes[i].num_children * sizeof(*petriNet.nodes[i].childs.data());