Это проблема дизайна (я знаю, почему это происходит, просто хочу посмотреть, как люди справляются с ней). Предположим, у меня есть простой связанный список struct
:
struct List {
int head;
std::shared_ptr<List> tail;
};
shared_ptr
позволяет обмениваться подсписками между несколькими списками. Однако, когда список становится очень длинным, в его деструкторе может произойти переполнение стека (вызванное рекурсивными выпусками shared_ptr
s). Я попытался использовать явный стек, но это очень сложно, поскольку хвост может принадлежать нескольким спискам. Как я могу создать свой List
, чтобы избежать этой проблемы?
ОБНОВЛЕНИЕ: Чтобы уточнить, я не изобретаю колесо (std::forward_list
). List
выше - это только упрощенная версия реальной структуры данных. Реальная структура данных представляет собой ориентированный ациклический граф, который, если вы думаете об этом, - это всего лишь много связанных списков с общими хвостами/головами. Обычно копировать граф обычно не стоит дорого, поэтому необходим обмен данными.
ОБНОВЛЕНИЕ 2: Я думаю о явном пересечении цепочки указателей и std::move
, когда я иду. Что-то вроде:
~List()
{
auto p = std::move(tail);
while (p->tail != nullptr && p->tail.use_count() == 1) {
// Some other thread may start pointing to `p->tail`
// and increases its use count before the next line
p = std::move(p->tail);
}
}
Кажется, что это работает в одном потоке, но я беспокоюсь о безопасности потоков.