Пламенный куку!
В однопоточном режиме граф удаляется нормально. В многопоточном - крашимся. Но! В каждом потоке создается свой собственный граф. Вывел небольшой (не)рабочий пример.
item - лист графа, у него есть имя и дети. У двух листьев могут быть одинаковые дети. make() создает граф. Отдельно объекта для представления графа нет, удаление ячеек делается через метод deleteIt().
class item{
public:
item(QString const &n, item *parent = 0) :name(n), del(false){
if (parent != 0)
parent->addChild(this);
}
void addChild(item *i){
childs.push_back(i);
}
void deleteIt(){
if (!del){
del = true;
while (childs.count() > 0){
auto child = childs[0];
childs.removeFirst();
child->deleteIt();
}
delete this;
}
}
QList<item*> childs;
QString name;
bool del;
protected:
~item(){}
};
item *make(){
auto root = new item("init");
auto step = new item("step 1", root);
auto step2 = new item("step 2");
step->addChild(step2);
auto step3 = new item("step 3", step);
step3->addChild(step2);
return root;
}
int main(int argc, char **argv){
QCoreApplication a(argc, argv);
for (int i = 0; i < 5; i++){
auto thread = std::thread([](){
for (int i = 0; i < 10000; i++){
qDebug() << i;
auto it = make();
it->deleteIt();
}
});
thread.detach();
}
a.exec();
}
Падаем рандомно в deletIt при обращении к списку детей, в деструкторе и изредка в addChild. Иногда почти сразу, иногда на второй-третьей тысяче итераций. Если оставляем один поток или исключаем добавление одинакового ребенка к двум разным элементам графа, все работает нормально.
Может быть создание объекта для представления графа, который хранил бы его уникальные листья, помогло бы, но в первую очереь хочу понять причину краша. Есть какая-то зацепка на уровне интуиции, что в одном потоке удаляется объект, в другом создается новый по тому же адресу, и после этого что-то идет не так. Но полноценную картину падения выстроить не получается.
Версию компилятора говорить не буду, чтоб не отправляли на винфак, по возможности позже попробую прокрутить пример на линупсе, хотя, думаю, дело едва ли в компиляторе.