使用动态结构数组返回结构的结构

时间:2017-12-28 20:37:35

标签: c++ struct dynamic-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;
};

我想初始化并返回外部结构,如下所示:

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)是正确的。如果我在返回之前在函数内打印,一切正常。我还能做什么来返回动态分配的内存?

1 个答案:

答案 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());