LINUX.ORG.RU

[РЕШЕНО] Откуда segfault?

 , ,


0

2

Здравствуйте. Имеется QListWidget* menuAppsList и QString mask. Пишу функцию для поиска по меню приложений:

void AppMenu::searchApps(QListWidget* menuAppsList, QString mask) {
    QList<QListWidgetItem*> searchResults = menuAppsList->findItems(mask, Qt::MatchContains);
    menuAppsList->clear();
    foreach (QListWidgetItem* item, searchResults) {
        menuAppsList->addItem(item);
    }
}

При обращении к элементу item (будь то item->text() или добавление в QListWidget - получаю Segmentation Fault). Пробовал по-разному (составлять список searchResults вручную циклом, тоже самое; пробовал динамически выделять память под список searchResults - тоже самое). Проходился дебагом, доходит до ассемблера. Проблема кроется именно где-то в функции, т.к., перенеся функцию в новый проект без сигналов и слотов, получаю тот же segfault. Подскажите, пожалуйста, в чем может быть проблема. Спасибо.



Последнее исправление: thm (всего исправлений: 7)

Ответ на: комментарий от vvviperrr

Но я пробовал не обращаться к item, а добавить пункты «Hello, World!» и все работало https://i.ibb.co/zsdh5FY/Screenshot-from-2022-03-13-01-26-18.png

UPD: с другой стороны, убрал clear(), сделал добавление (item->text()) (т.к. добавление одинаковых QListWidgetItem - undefined behaviour). Работает. Вопрос - почему ->clear() вызывает segfault?

thm
() автор топика
Последнее исправление: thm (всего исправлений: 8)
Ответ на: комментарий от thm
void QListWidget::clear()

Removes all items and selections in the view.

Warning: All items will be permanently deleted.

Судя по всему, там внутри вызывается деструктор для элементов, которыми владеет список. Не лез в исходники, но рекомендую залезть и проверить.

ploskov
()
Ответ на: комментарий от thm

А вот и нашёл доказательство:

void QListModel::clear()
{
    beginResetModel();
    for (int i = 0; i < items.count(); ++i) {
        if (items.at(i)) {
            items.at(i)->d->theid = -1;
            items.at(i)->view = nullptr;
            delete items.at(i);
        }
    }
    items.clear();
    endResetModel();
}

https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/itemviews/qlistwidget.cpp

Ты сохраняешь себе в список указатели на элементы, которые удаляются во время вызова clear(), поскольку список владеет своими элементами.

ploskov
()

Безотносительно топика: в Qt действительно мерзкая модель владения. Она работает для простых случаев, но при попытке написать что-то сложное приходится сильно заморачиваться с лайфтаймами и отслеживать каждый указатель. Это обуславливается историей Qt и было придумано во времена древнего С++. Сейчас можно и нужно лучше, но увы.

По теме уже ответили, повторяться не буду.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Да нормальная там модель владения. Надо просто извлечь элементы из списка, а не вызывать clear().

X512 ★★★★★
()
Ответ на: комментарий от X512

Я же ясно указал, что мое суждение не относится к теме.

Siborgium ★★★★★
()
Ответ на: комментарий от aiqu6Ait

ты всерьез думаешь, что я читал ОП? какой ты скучный

Virtuos86 ★★★★★
()
Ответ на: комментарий от thm

Есть ещё вариант: не вытаскивать/закидывать всё в список, поскольку это может вызвать несколько реаллокаций, а попробовать пробежаться по элементам и скрыть ненужные.

ploskov
()
Ответ на: комментарий от Siborgium

Нормальная модель. Просто почему-то в последнее время особенно среди модерновых плюсовиков появилась тенденция к гипер-переусложнению кода с использованием синтаксического сахара так что бы из ушей лезло… Вот только вычислительного преимущества оно как правило не дает…

Jetty ★★★★★
()

В конце концов, решил на каждое изменение QLineEdit перестраивать список заново с проверкой на совпадение. Проверю чуть позже, насколько это сильно потребляет ресурсы.

thm
() автор топика
Ответ на: комментарий от unC0Rr

Не-не-не. Если уж ассоциации то это скорее пересел на супербайк, научившись ездить на трамвае.

Elyas ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.