Russian Qt Forum
Ноябрь 24, 2024, 05:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Почему сегфолт в деструкторе?  (Прочитано 10277 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« : Январь 17, 2016, 01:31 »

Имею класс, в котором создается виджет таблицы QTableWidget, указатель на который хранится в свойстве table:

Код:
table=new QTableWidget(0, colsName.count(), this);
table->setHorizontalHeaderLabels(colsName);


В процессе работы класса в таблицу добавляются строки. Ячейки строк заполняются QTableWidgetItem * или виджетами, вставляемыми через QTableWidget::setCellWidget();

В деструкторе необходимо пробежать всю таблицу и удалить итемы и вставленные виджеты.

Я это делаю так:

Код:
Downloader::~Downloader()
{
  // Удаляется содержимое таблицы
  for(int i=0; i<table->rowCount(); i++) // <-- Тут сегфолт!
  {
    delete table->item(i, downloadReferenceCol);
    delete qobject_cast<QProgressBar *>( table->cellWidget(i, downloadReferenceCol) );
  }

  delete table;
  delete cancelButton;
}


Но получаю сегфолт на строке с циклом при выполнении самой первой итерации.

Скриншот:

http://i.piccy.info/i9/053bea8edbb2549fea811c231e4af339/1452982758/389884/825956/scr_374.png

Видно, что table существует, и содержит какой-то адрес. Но выражение table->rowCount() почему-то не высчитывается. И получается сегфолт.

Вопрос: из-за чего появляется такой сегфолт?
Записан

Собираю информацию по крупицам
http://webhamster.ru
Bepec
Гость
« Ответ #1 : Январь 17, 2016, 02:47 »

Ну во 1 вы не привели код создания table (точнее привели кусок, а место не привели).
во 2 - вы делаете плохую бяку. Вы удаляете итем, при этом table свято уверен что итем остался.
в 3 - то же самое с прогрессбаром.
в 4 - приведите значение i. Скорее всего сегфолт вылетает эдак на 2-3, мб даже больше итерации цикла.
в 5 - вы указали table родителя. То есть родитель сам удалит ваш table.
в 6 - приводите весь код Улыбающийся

PS дебаггер в руки и точку остановки на деструктор table. Так и разберётесь.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Январь 17, 2016, 06:58 »

2 xintrea
А покажите весь стек возвратов.

2 Bepec
Вы сообщения вообще читать перестали? Написали кучу притензий, а они все раскрыты в сообщении...
Записан
Bepec
Гость
« Ответ #3 : Январь 17, 2016, 08:50 »

to Old:
По пунктам
1. нет места в коде, где кусок создания находится. Т.е. понять где он создаётся и при каких обстоятельствах хз.
2,3,4 - не раскрыто от слова вообще
5. Без комментариев.
6. Без комментариев.

Где тут раскрытость всех пунктов?

И да добавлю - то что объект существует не значит, что он там есть. Он может быть уже удалён, просто данные не затерты.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Январь 17, 2016, 09:46 »

1. нет места в коде, где кусок создания находится. Т.е. понять где он создаётся и при каких обстоятельствах хз.
А какая разница, в каком месте создается объект? Главное что он создается.

2,3,4 - не раскрыто от слова вообще
Если итема или прогресбара нет, то вернется nullptr, а delete с этим легко справляется. Из-за этого ничего падать не будет. К тому-же падение происходит раньше.
По поводу 4 пункта, откройте картинку и посмотрите, там есть ответы на все ваши вопросы. Ну и ТС четко написал на какой итерации происходит падение.

5. Без комментариев.
Не имеет значение, указал он родителя или не указал. Он всегда сможет удалить объект руками.

6. Без комментариев.
ТС не раз приводил ссылки на github со своим проектом. Если бы он был вам нужен, вы бы легко его нашли: https://github.com/xintrea/mytetra_dev
« Последнее редактирование: Январь 17, 2016, 10:13 от Old » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Январь 17, 2016, 12:49 »

Попробуйте пересобрать проект. У меня не вылетает сегфолта. Валгринд выдаёт только утечки памяти, но это не влияет на сегфолт
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Январь 17, 2016, 13:40 »

Если "вылетает стабильно", то это не проблема. Я бы "покрутил" немного, напр так

1) Вставить в тело цикла
Код
C++ (Qt)
qDebug() << "deleting" << i << "of" << table->rowCount();

2) Закомментировать оба delete в цикле, потом по одному

3) Ну и "Rebuild All" (как уже советовали) тоже лишним не будет

Обычно после таких простых действий ситуевина быстро проясняется


Записан
Bepec
Гость
« Ответ #7 : Январь 17, 2016, 14:06 »

Кто то где то порушил память скорее всего. А вылет уже следствие.

Никаких новых работ с массивами информации не добавляли?

to Old: чесслово я помню только 1 человека с проектом и это QSerialPort. Остальное как то не отложилось Веселый
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #8 : Январь 17, 2016, 14:28 »

PS дебаггер в руки и точку остановки на деструктор table. Так и разберётесь.

Разобрался. Я опять забыл что указал родителя (this) при создании QTableWidget. И при delete table у меня шло двойное удаление объекта.
Записан

Собираю информацию по крупицам
http://webhamster.ru
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #9 : Январь 17, 2016, 14:35 »

Попробуйте пересобрать проект. У меня не вылетает сегфолта. Валгринд выдаёт только утечки памяти, но это не влияет на сегфолт

С какими опциями запускали valgrind? У меня он показывает утечки даже в библитечных методах. Если несложно, покажите опции и лог валгринда на http://pastebin.com.
Записан

Собираю информацию по крупицам
http://webhamster.ru
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Январь 17, 2016, 14:52 »

Разобрался. Я опять забыл что указал родителя (this) при создании QTableWidget. И при delete table у меня шло двойное удаление объекта.
Не может этого быть. Из-за этого не бывает двойного удаления.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #11 : Январь 17, 2016, 14:56 »

С какими опциями запускали valgrind? У меня он показывает утечки даже в библитечных методах. Если несложно, покажите опции и лог валгринда на http://pastebin.com.
Я его запускаю из qtcreator, а там уже можно фильтр настроить, чтобы не показывал внешние ошибки.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #12 : Январь 17, 2016, 15:00 »

Разобрался. Я опять забыл что указал родителя (this) при создании QTableWidget. И при delete table у меня шло двойное удаление объекта.
Дополню комментарий old.
У вас при "первом" удалении посылается сигнал родителю о том, что объект ликвидирован. Таким образом родитель не станет второй раз освобождать память.
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #13 : Январь 17, 2016, 15:24 »

Я его запускаю из qtcreator, а там уже можно фильтр настроить, чтобы не показывал внешние ошибки.

Сделайте, пожалусто, скриншот фильтров valgrind (проще положить на piccy.info).

И лог на pastebin.com.
Записан

Собираю информацию по крупицам
http://webhamster.ru
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #14 : Январь 17, 2016, 16:22 »

Картинка. Как из creator экспортировать лог - не знаю. В терминале лог засоряется дебажными сообщениями из приложения и как переправить валгридовский выхлоп в файл тоже не знаю. Проверку в терминале запускаю с помощью
Код:
valgrind --leak-check=full ./mytetra
Зато знаю, как в xml формате заставить валгрид записывать. Во вложении отчёт, который можно открыть в qtcreator на вкладке анализа.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.089 секунд. Запросов: 23.