|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
|||||||||||
Работа с std::vector содержащим указатели21.11.2017, 12:27. Показов 2540. Ответов 49
Метки нет (Все метки)
Привет! Я долгое время находился в ридонли, решил всё же задать вопрос, так как проблему не получается решить самостоятельно, из-за нехватки знаний по всей видимости. Оговорюсь, что на момент как я решил выучить c++, я уже хорошо знал несколько языков в том числе python java php и так далее.
Пишу небольшую игру на С++, кодовая база получилась уже сейчас довольно большая (для меня как только-только изучающего с++). Всё бы хорошо кроме одного момента. В программе есть вектор содержащий все сущности игры вида:
и вызова у каждой из них ->update(), всё в принципе стандартно. Всё работает хорошо и как нужно кроме одного момента: Периодически абсолютно в неясные для меня моменты (то есть какой либо зависимости у этих событий нет) получаю segfault либо на ->update(); (если я компилирую в g++) либо на сортировке объектов, в случае добавления новых сущностей для сохранения порядка отрисовки (если компилирую в msvc). segfault вызванный тем, что я пытаюсь вызвать метод объекта из вектора, при том что указатель ссылается на чистую область памяти (то есть объекта там уже нет) Разработку веду в clion (gcс + mingw) И периодами сверяюсь с msvc (там удобный профайлер, да и в целом компилятор по умолчанию более строгий). Понятно что весь код внутри update, я физически привести не смогу, вопрос вот в чем, может быть есть какие-то методики для понимания кто и в каком месте заменяет на heap'e реальные объекты таким образом, что указатель ведёт на чистую область памяти где не содержится изначально искомого объекта? Либо же я просто совершаю некую распространенную ошибку новичка и каким-то не правильным образом работаю с вектором таким образом что при наступлении определенных событий происходит segfault? Сразу оговорюсь, resize() у вектора я сам не вызываю, то есть аллокация новых элементов происходит автоматом и происходит успешно до какого-то момента. Так же я могу привести кусок кода на котором возникает (в случае неопределенных обстоятельств) segfault при gcc компиляции.
0
|
|||||||||||
| 21.11.2017, 12:27 | |
|
Ответы с готовыми решениями:
49
Как передать целочисленную матрицу типа std::vector<std::vector<int> > в функцию? Вывести значения std::vector<std::vector<int*> > |
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
||||||
| 21.11.2017, 17:15 | ||||||
![]() Окей, тогда попробуй переписать цикл:
0
|
||||||
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
|
| 21.11.2017, 17:15 [ТС] | |
|
0
|
|
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
|
| 21.11.2017, 17:25 | |
|
mrAndersen7, понимаю что глупо, но всё же, не изменяете-ли вы косвенно или напрямую вектор items из метода update?
0
|
|
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
|||
| 21.11.2017, 17:37 [ТС] | |||
|
Добавлено через 1 минуту
0
|
|||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|||||||
| 21.11.2017, 17:45 | |||||||
|
При добавлении элементов, итераторы вектора могут стать невалидными.
Вот пор push_back:
Рекомендую попробовать сделать так, как я писал выше, только чуть изменив:
А новые значения element в моём цикле тоже принимают эти "странные значения"?
0
|
|||||||
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
|||||||
| 21.11.2017, 17:59 [ТС] | |||||||
Но вот сортировка может быть вызвана и в середине цикла итерации.
0
|
|||||||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
||||||
| 21.11.2017, 18:05 | ||||||
(Entity *&a, Entity *&b).Добавлено через 1 минуту И вызывай сортировку после цикла update Потому что это точно портит итераторы, да и мою идею с индексами тоже. И это очень неоптимально.
0
|
||||||
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
||
| 21.11.2017, 18:07 [ТС] | ||
|
0
|
||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|
| 21.11.2017, 18:09 | |
|
Пожалуй, залей куда-нибудь на github проект, тут уже так не разобраться.
0
|
|
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
||
| 21.11.2017, 20:10 [ТС] | ||
|
https://pastebin.com/qsLpw41P - Менеджер сущностей
Добавлено через 1 час 48 минут
0
|
||
|
зомбяк
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
||||||
| 21.11.2017, 20:32 | ||||||
|
Ошибка в этом
*e, в которой указатель.Добавлено через 3 минуты Да, ошибся. e тут не итератор, а просто ссылка.
0
|
||||||
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
||
| 21.11.2017, 20:36 [ТС] | ||
0
|
||
|
зомбяк
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
||||||
| 22.11.2017, 04:42 | ||||||
|
Возможно у Entity (и дочерних классов) не виртуальный деструктор, потому не доудаляются...
Добавлено через 3 часа 3 минуты И ещё добавить проверку на дублирование элементов при удалении
0
|
||||||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|
| 22.11.2017, 09:36 | |
|
Скинь вообще весь проект для MS VS, попробую подебажить.
0
|
|
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
|||
| 22.11.2017, 10:13 | |||
|
Тут, похоже что во время выполнения той или иной операции, будь она в цикле или в лямбде (касательно sort), текущий итератор (хоть его и не видно, но он есть) становится невалидный, а произойти это может если в одном или нескольких методах из: getDrawOrder, getWorldCoordinates или update - происходит изменение вектора items, например создаётся один или несколько объектов, которые в конструкторе себя добавляют в items. Как бы инвалидация итератора в "renge base for" цикле может быть только в результате каких-либо действий в теле этого цикла (исключая многопоточность).
0
|
|||
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
|||||||||
| 22.11.2017, 11:55 [ТС] | |||||||||
0
|
|||||||||
|
зомбяк
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
|||||||
| 22.11.2017, 12:33 | |||||||
|
При тестировании с полуслучайным добавлением-удалением, если отключить всю работу с itemsByGroup, SEGFAULT вылетало из-за дублирования элементов в itemsToRemove, когда для адреса элемента, к которому уже применялось delete e , повторно проходит итератор. Но это не единственная остановка, иногда останавливалось на вот этом - Ntdll!DbgBreakPoint signal-received - остановка выполнения - и с чем это связано, не понимаю. После продолжения программа успешно выполнялась. Если нет уверенности, что в void remove(Entity *item) попадают валидные адреса, теоретически можно сделать так:
0
|
|||||||
|
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
|
||
| 22.11.2017, 14:23 | ||
|
Добавлено через 5 минут Вот грубый пример того, как можно поймать sigsegv при невалидном итераторе: http://rextester.com/EYM23196 если в коде убрать один update() в main, то ошибки уже не будет.
0
|
||
|
зомбяк
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
|||||||
| 22.11.2017, 15:08 | |||||||
aaa.size() и aaa[i] значения сохранят актуальность даже после реаллокации вектора aaa, в отличии от итераторов или ссылок в новой форме записи for. Хотя конечно будет проигрыш по производительности.
0
|
|||||||
|
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
|
|||||||||||
| 22.11.2017, 15:52 [ТС] | |||||||||||
|
Закомментил сортировку в принципе, для теста. Проблема пропала как таковая. Сейчас попробую добавление элементов класть в очередь (новый вектор) и суммировать вектора в конце фрейма
Добавлено через 36 минут В общем ситуация такая. Было изначально 2 места где был segfault на update() и на сортировке. В том месте где был update - он возникал, потому что была инвалидация итератора, по причине добавления в вектор новых сущностей, она решилась таким образом (как было предложено выше и на предыдущей странице):
Проблема с segfault на сортировке не решилась, даже при том условии что происходит она только после всех операций update и итерации по вектору, таким вот образом:
Добавлено через 2 минуты UPD: Проблема с segfault на сортировке присутсвтует только при компиляции через mingw + gcc, при комплияции через MSVC - проблемы нет, перепроверил несколько раз
0
|
|||||||||||
| 22.11.2017, 15:52 | |
|
Помогаю со студенческими работами здесь
40
Как изменять размер std::vector<std::vector>? Std::vector<std::pair<std::vector<int>::iterator, std::vector<int>::iterator>
Реализация класса MyString. Стандартная библиотека, std::string, std::vector Передача функции указатель на элемент std::vector<std::string> Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях.
Задача: при копировании документа очищать определенные реквизиты и табличную. . .
|
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git
main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели
8ATzM_2aurI
|
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2.
Задача: запретить редактирование документа, если он открыт у другого пользователя.
/ / . . .
|
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои.
А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
|
|
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
kYBz3eJf3jQ
|
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
|
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
|
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора
Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2.
Задача: уведомлять пользователя, если. . .
|