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_NodeC_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());