Return 具有动态结构数组的结构的结构
Return struct of structs with dynamic struct arrays
我有一个包含动态结构数组的结构:
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;
};
我想像下面这样初始化和 return 外部结构:
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)是正确的。如果我在 returning 之前在函数内部打印,一切正常。我还能对 return 动态分配的内存做些什么?
问题是 petriNet
是传递给您的函数的对象的本地副本。您正在创建的新 C_Node
和 C_Transition
中保存指向 petriNet
中各种向量的 data()
的指针,但是当函数 returns.
如果您更改函数以获取引用,只要调用者的对象还活着,指针就会保持有效,但这仍然很脆弱。您真正需要做的是复制所有数据。所以你可以使用 memcpy()
:
memcpy(c_nodes[i].children, petriNet.nodes[i].childs.data(), c_nodes[i].num_children * sizeof(*petriNet.nodes[i].childs.data());
我有一个包含动态结构数组的结构:
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;
};
我想像下面这样初始化和 return 外部结构:
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)是正确的。如果我在 returning 之前在函数内部打印,一切正常。我还能对 return 动态分配的内存做些什么?
问题是 petriNet
是传递给您的函数的对象的本地副本。您正在创建的新 C_Node
和 C_Transition
中保存指向 petriNet
中各种向量的 data()
的指针,但是当函数 returns.
如果您更改函数以获取引用,只要调用者的对象还活着,指针就会保持有效,但这仍然很脆弱。您真正需要做的是复制所有数据。所以你可以使用 memcpy()
:
memcpy(c_nodes[i].children, petriNet.nodes[i].childs.data(), c_nodes[i].num_children * sizeof(*petriNet.nodes[i].childs.data());