У меня есть структура графа в C, и я хочу сделать ее полную копию (включая узлы и ребра).
Структура выглядит так:
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;
};
Эти структуры существуют не сами по себе, а "наследуются" в другой структуре, например:
struct ex_node {
struct gr_node _; // "Superclass"
int id;
struct ex_node *union_find_parent;
...
}
Существует ли элегантное решение для создания глубокой копии такой структуры, включая обновление ссылок на копии?
Примечание. Члены вложенных структур указывают не на корневую структуру, которая в них содержится, а на связанные с ними вложенные структуры (например, ex_node._.pred.n.next
указывает на ex_edge._.pred
). Это подразумевает утомительную арифметику указателей, когда они должны быть обновлены.
Мое решение до сих пор -
- Memcopy все структуры
- Итерация по всем копиям
- Вызвать кучу макросов для всех полей, которые содержат ссылки (из-за отсутствия RTTI в C, я, вероятно, не схожу с этим)
- Использование макросов
offsetof
для вычисления адреса корневой структуры
- Получить адрес скопированного эквивалента
offsetof
чтобы указатель указывал на правильную вложенную структуру
Есть ли более простой способ сделать это? Я также боюсь, что забуду добавить вызов макроса, когда добавлю больше полей.