Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Qt
Войти
Регистрация
Восстановить пароль
 
quirkbuzz
0 / 0 / 0
Регистрация: 21.02.2017
Сообщений: 7
1

Удаление объектов массива QVector

20.12.2017, 15:11. Просмотров 320. Ответов 9
Метки нет (Все метки)

Здравствуйте.
Имеется массив указателей
C++ (Qt)
1
QVector<BNWorker*> bnworkersList;
В программе в этот массив постоянно добавляются новые указатели на объекты BNWorker, созданные оператором new, и отработанные объекты необходимо периодически удалять из памяти и из массива, чтобы не засорять память.
Однако оператор delete, примененный к отработанным объектам массива, почему-то не удаляет объекты на самом деле. Написал код, предназначенный специально для проверки удаления объектов.

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for(int i = bnworkersList.size() - 1; i >=0; i--) {
    if(bnworkersList[i]->isFinished) {
        qDebug() << "BNWorker with index"  << i << "is finished.";
        delete bnworkersList.value(i);
    }
}
 
for(int i = 0; i < bnworkersList.size(); i++) {
    try {
        bnworkersList.value(i)->setSomeStringValue(QString("1234567890"));
        bnworkersList.value(i)->temp004 = 1000.09;
        qDebug() << bnworkersList.value(i)->getSomeStringValue();
        qDebug() << bnworkersList.value(i)->temp004;
    }
    catch(std::exception e) {
        qDebug() << e.what();
    }
}
Таким образом, в первом bnworkersList.value(i) возвращает указатель на объект BNWorker, этот объект удаляется оператором delete, но сам указатель из массива не удаляется (для последующей проверки правильности удаления).
Во втором цикле происходит обращение к методам и полям объекта, которые должны быть удалены в первом цикле.

И в самом деле, во время работы первого цикла в лог вываливаются сообщения о том, что деструкторы объектов вызываются:

BNWorker with index 7 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 6 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 5 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 4 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 3 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 2 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 1 is finished.
virtual BNWorker::~BNWorker()
BNWorker with index 0 is finished.
virtual BNWorker::~BNWorker()

Но во время работы второго цикла в лог благополучно вываливаются значения измененных полей якобы удаленных ранее объектов:

"1234567890"
1000.09
"1234567890"
1000.09
"1234567890"
1000.09
"1234567890"
1000.09
"1234567890"
1000.09
"1234567890"
1000.09
"1234567890"
1000.09
"1234567890"
1000.09

С чем это может быть связано? Может быть, из-за того, что BNWorker унаследован от QObject, или здесь какие-то другие причины?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.12.2017, 15:11
Ответы с готовыми решениями:

Удаление объектов из массива
Добрый день. Забыл следующее: в некотором объекте в приватной зоне есть массив...

QMap<int, QVector<float>> копирование QVector<float> в другой вектор
Добрый вечер. У меня есть функция FaceSearchDB. Я хочу копировать значения из...

Удаление объектов в Qt
Не пинайте уж сильно, второй день осваиваю сие творение... и возник вопрос: ...

Удаление объектов из компановщика
Вообщем создал 2 QSpinBox'a (2 для красоты). 1 соединён с пользовательским...

Безопасное удаление объектов
Есть какой то объект, который принимает постоянно данные через сигналы. В какой...

9
Avazart
Эксперт С++
7759 / 5664 / 555
Регистрация: 10.12.2010
Сообщений: 25,671
Записей в блоге: 17
20.12.2017, 15:17 2
delete удаляет сами объекты, но не удаляет указатели на них из контейнера.

Можно использовать смартпоинтеры.

C++ (Qt)
1
QVector< QSharedPointer<BNWorker> > bnworkersList;
И удаляеть через remove() или erase()
0
quirkbuzz
0 / 0 / 0
Регистрация: 21.02.2017
Сообщений: 7
20.12.2017, 15:21  [ТС] 3
Цитата Сообщение от Avazart Посмотреть сообщение
delete удаляет сами объекты, но не удаляет их указатели на них из контейнера.
Это-то я знаю. Но в моем коде delete почему-то именно сами объекты и не удаляет! Иначе попытки оперировать объектами и вызывать их методы через указатели приводили бы к ошибкам.
0
Avazart
Эксперт С++
7759 / 5664 / 555
Регистрация: 10.12.2010
Сообщений: 25,671
Записей в блоге: 17
20.12.2017, 15:24 4
Удаляет.

Цитата Сообщение от quirkbuzz Посмотреть сообщение
Иначе попытки оперировать объектами и вызывать их методы через указатели приводили бы к ошибкам.
Удаление это лишь "табличка свободно" на области памяти, сам объект может так и продолжать там лежать где лежал, до тех пор пока его место не займет другой объект (затерев прошлый).



C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
for(int i = bnworkersList.size() - 1; i >=0; i--) 
{
    if(bnworkersList[i]->isFinished) 
    {
        qDebug() << "BNWorker with index"  << i << "is finished.";
        
        delete bnworkersList.value(i);
 
        bnworkersList.remove(i); //  !!!
    }
}
0
quirkbuzz
0 / 0 / 0
Регистрация: 21.02.2017
Сообщений: 7
20.12.2017, 15:27  [ТС] 5
C++ (Qt)
1
bnworkersList.remove(i); //  !!!
Этот код просто удаляет указатель из массива. Сам по себе объект, на который ссылается этот указатель, он не удаляет. Я проверял, метод remove не вызывает деструктор объекта BNWorker, т. е. в лог не валится сообщение

virtual BNWorker::~BNWorker()

А если использовать delete, то это сообщение появляется.
0
Avazart
Эксперт С++
7759 / 5664 / 555
Регистрация: 10.12.2010
Сообщений: 25,671
Записей в блоге: 17
20.12.2017, 15:30 6
Цитата Сообщение от quirkbuzz Посмотреть сообщение
Этот код просто удаляет указатель из массива.
Эта строчка после delete.
Если использовать смарт поинтер удаление будет автоматическим, delete не обязателен.
0
quirkbuzz
0 / 0 / 0
Регистрация: 21.02.2017
Сообщений: 7
20.12.2017, 16:02  [ТС] 7
Цитата Сообщение от Avazart Посмотреть сообщение
Эта строчка после delete.
Все-таки хотелось бы разобраться именно с delete. После удаления указателей из массива объекты станут недоступны, а оператор delete, как мы выяснили, фактически объекты из памяти не удаляет. Т. е. если применить оператор delete, а затем удалить указатели, то объекты останутся висеть недоступным мертвым грузом где-то в памяти.
0
Avazart
Эксперт С++
7759 / 5664 / 555
Регистрация: 10.12.2010
Сообщений: 25,671
Записей в блоге: 17
20.12.2017, 16:28 8
quirkbuzz, Вы читать научитесь то что вам отвечают, еще раз:

Цитата Сообщение от Avazart Посмотреть сообщение
Удаление это лишь "табличка свободно" на области памяти, сам объект может так и продолжать там лежать где лежал, до тех пор пока его место не займет другой объект (затерев прошлый).
Поэтому падения приложения может и не быть как такого, это как повезет.
0
TRam_
зомбяк
789 / 725 / 231
Регистрация: 14.05.2017
Сообщений: 2,480
20.12.2017, 16:32 9
Цитата Сообщение от quirkbuzz Посмотреть сообщение
delete, как мы выяснили, фактически объекты из памяти не удаляет
quirkbuzz, фактически из памяти объекты удалятся, если вытащишь планку оперативной памяти. Или если выключишь питание. А так память либо отнесена в пользование программе, либо не отнесена. После удаления объектов память в куче освобождается (т.е. перестаёт относиться к данной программе).

Конкретно в в случае без smartpointer'ов нужно вначале удалить объект, потом удалить указатель на этот объект (смотри код в посте #4).

Если используются QVector< QSharedPointer<BNWorker> >, то и добавлять объект надо специальным образом:
C++ (Qt)
1
bnworkersList.push_back( QSharedPointer<BNWorker>(new BNWorker() ) );
Тогда указатель, когда его будут удалять, сам вызовет delete для указываемого объекта. При условии что копия этого указателя нигде больше не лежит (т.к. тогда должна быть удалена и та копия)
0
quirkbuzz
0 / 0 / 0
Регистрация: 21.02.2017
Сообщений: 7
20.12.2017, 16:44  [ТС] 10
Цитата Сообщение от Avazart Посмотреть сообщение
Удаление это лишь "табличка свободно" на области памяти, сам объект может так и продолжать там лежать где лежал, до тех пор пока его место не займет другой объект (затерев прошлый).
Спасибо, теперь понятно. Сперва не заметил эту строчку.
0
20.12.2017, 16:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.12.2017, 16:44

Удаление объектов и дебагер
Не уверен, что смогу правильно сформулировать вопрос. У меня есть класс окна -...

Удаление динамически созданных объектов
добрый день. чувствую себя полным нубом)) столкнулся с проблемой: на...

Удаление объектов, на которые ссылаются переменные-члены класса
Во многих примерах по Qt в конструкторе, например, диалога, при помощи new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru