I have a graph structure in C and want to make a deep copy of it (including nodes and edges).
The structure looks like this:
struct li_list {
struct li_node n;
};
struct li_node {
struct li_node *next, *prev;
};
struct gr_graph {
struct li_list nodes;
int nodecount;
};
struct gr_node {
struct li_node node;
struct gr_graph *graph;
int pred_count, succ_count;
struct li_list pred, succ;
};
struct gr_edge {
struct li_node succ, pred;
struct gr_node *from, *to;
unsigned long marks;
};
These structs do not exist as themselves, but "inherited" in another struct, like this:
struct ex_node {
struct gr_node _; // "Superclass"
int id;
struct ex_node *union_find_parent;
...
}
Is there an elegant solution of creating a deep copy such a structure, including updating references to the copies?
Note: Members of nested structs do not point to the root struct it contains, but to their related nested struct (for instance, ex_node._.pred.n.next
points to a ex_edge._.pred
). This implies tedious pointer arithmetic when these must be updated.
My solution up to now is
- Memcopy all structs
- Iterate through all copies
- Call a bunch of macros for all fields that contain references (Due to missing RTTI in C, I probably won't come around this)
- The macros use
offsetof
to calculate the address of the root struct- Retrieve the address of the copied equivalent
offsetof
to make the pointer point to the correct nested struct
Is there any easier way to do this? I am also afraid that I forget to add a macro call when I add more fields.