![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Здравствуйте. Столкнулся со странной проблемой.
У меня есть класс CMyList унаследованный от std::list В классе есть 1 метод добавляющий элемент в список и 4 удаляющих. Все они при этом защищены критической секцией. Несмотря на это в следующей функции иногда получаю невалидный итератор:
Иногда на строке SAFEDEL(*it); получаю итератор it = 0xfeeefeee и соответственно дебажная CRT мне говорит "list iterator not dereferencable". Откуда такой итератор мог здесь взяться? Это сообщение отредактировал(а) nerdy_weirdie - 16.2.2011, 23:31 |
|||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
студийный stl должен быть потокобезопасным, зато в коде есть ошибка
[0 1 2 ->3] после erase [0 1 2 ->] ++it ? |
|||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Спасибо за ответ!
Что-то не нахожу ошибку. После erase идет break; и итератор не инкрементируется. |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
||||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
да, извините, осмотрелся
попробуйте поставить на входе в метод дебажный вывод, чтоб посмотреть кто перед ошибкой приходит, и правильно ли работает критическая секция а что SAFEDEL делает? еще в критических секция должны быть все куски кода, где идет доступ к его содержимому |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Напишите так:
|
|||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
volatile, по break'у он из цикла выйдет
|
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
||||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Спасибо за советы, разобрался. Как раз дебажный вывод и обращался по невалидному итератору )) но дебагер почему-то тыкал меня в совершенно другую строку. Модератор, удалите пожалуйста тему
|
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
||||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
volatile, много раз слышал это из разных источников, но не могу понять, почему именно ? Спасибо. чевойта ? -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Вот и я не пойму. Он потокобезопасен если много читают и никто не пишет. Если хоть кто-то пишет но ни какой потокобезопаности. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Вообще-то стандарт C++ даже в этом случае не гарантирует безопасности, вдруг какой нибудь умник взял и написал модифицирующий код в read-only функции. Вряд ли конечно, но чем черт не шутит..В общем случае конечно можно полагаться на современные реализации и считать, что чтение потокобезопасно, но только чтение. Ну да. Такого вообще быть не может, ведь потокобезопасность контейнера здорово снижает его производительность. Никто не станет делать потокобезопасным все контейнеры. Максимум делают две версии. Это сообщение отредактировал(а) azesmcar - 17.2.2011, 10:57 |
|||
|
||||
| baldina |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
проще std::list::remove_if():
|
||||||
|
|||||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
baldina, в твоём случае удаляться все элементы, а в варианте с while - только первый, т.к. там стоит break;
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
это обозначает, что в многопоточной среде в условиях когда доступ к объектам stl'a идет раздельно ничего само не взорвется
|
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 1 Всего: 10 |
alexvs11, и какое нам дело до "The SGI implementation of STL" ?
|
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
alexvs11
1. В visual C++ (по умолчанию) стоит dinkumware, а не SGI. 2.
это означает, что доступ к разным контейнерам, разными потоками безопасен (еще бы, только этого нам не хватало
чтение общих контейнеров потокобезопасно, это гарантия реализации от SGI, тем не менее стандарт такой гарантии не дает. Вот он! Контейнер потокобезопасен для чтение, но не для записи. Если мы вернемся к исходнику в первом посте, мы увидем, что ТС пытается удалить элемент из контейнера, что никак нельзя назвать чтением. |
||||
|
|||||
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
и к std::istream ? если говорить только о SLT-контейнерах, то понятно, что вызsвать функции для чтения можно из разных потоков, правда никто не гарантирует, что сами потоки не будут изменять содержимое. Например, если вызывать ф-цию begin() из разных потоков, то она гарантировано вернёт одно и то же, если же в самом потоке писать в этот инетратор, то ...
так что говорить, что некорректно в студии используют Hewlett-Packard implementation, насколько я знаю. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
вы не поверите |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
alexvs11
Заметье, я ничего не писал по поводу второго сообщения. Я возразил против первого. Или вы продолжаете утверждать, что студийная реализация STL потокобезопасна? |
|||
|
||||
| alexvs11 |
|
||||||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
они прародители стандартного стла, привык читать маны оттуда, согласен что он не является стандартным на текущий момент http://www.sgi.com/tech/stl/ внизу подпись
между прочем Добавлено @ 16:11
я неправильно выразился, этим имел в виду, что если синхронизация правильная, то проблемы у автора, а не у stl'a а в многопоточной среде бывает что и при синхронизации работает не так, взять тот же небезопасный CreateThread и безопасный _beginthread Это сообщение отредактировал(а) alexvs11 - 17.2.2011, 16:13 |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
потому что исполнение стандартных контейнеров является логически финальной и расшить/изменить интерфейс не нарушив логической полноценности является трудно выполнимой задачей.. поэтому в общем случае их не рекомендует наследовать, особенно не приватно.. |
|||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
кстати, методы контейнера ведь и не обязаны быть виртуальными, правильно я понимаю?
тогда это вообще лишает принципиального смысла наследование - подсунуть под указателем list уже не удастся, а схожесть интерфейса решится обычным делегированием Это сообщение отредактировал(а) alexvs11 - 17.2.2011, 16:50 |
|||
|
||||
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
а почему, если я добавлю в deque такие ф-ции
я "нарушу локическую полноценность" ? mes, если не сложно, можете на конкретном примере пояснить, почему же наследоваться от stl - не есть хорошо ? Объяснение "а вот тут ты сам можешь потом забыть и (не)использовать эту штуку" - принимаются. Спасибо. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Добавлено @ 17:11
перенесено в соответствующую тему.. Это сообщение отредактировал(а) mes - 17.2.2011, 19:07 |
|||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
borisbn, концептуально наследование должно использоваться для специализации одной сущности к другой, общему deque к конкретному MyDeque, так чтобы конкретный MyDeque мог использоваться как специализированный MyDeque и как общий deque
но тут возникают две концептуальные проблемы 1) стандартный deque не предназначен для специализации ( отсутствие виртуальных функций, protected полей итп ). 2) само отсутствие виртуальных функций делает невозможное использование вашего MyDeque как общего deque там где наследование не приносит много пользы обычно используют агрегирование, тк дает те же результаты и связанность между классами будет меньше (при наследовании всегда железная связонность) Это сообщение отредактировал(а) alexvs11 - 17.2.2011, 17:20 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
тут больше подходит не "связанность", а "сцепление" или "зависимость".. Это сообщение отредактировал(а) mes - 17.2.2011, 17:32 |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
согласен на 99,9(9). создал -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
borisbn, есть признак: если деструктор не виртуальный, то класс не предназначен для наследования
а никто не говорил, что в данном случае что-то нарушится в этих функциях ничего страшного нет: они бесполезны, т.к. не расширяют семантику класса. а как только понадобится захочется создать действительно специализированную версию контейнера (путем наследования), начнутся проблемы: стандартные контейнеры не являются абстрактными классами с точки зрения языка: виртуальные функции использовать нельзя (деструктор невиртуальный), и функции доступа невиртуальные с другой стороны, стандартные контейнеры являются АТД, и в этом смысле их расширять не требуется. с третьей: если, скажем, нужно создать стек на основе списка, заимствуя при этом часть функций, технически удобно использовать наследование, но - закрытое. т.е. применить прием С++, не относящийся к ООП. кстати в stl стек так и сделан. еще пример: паттерны типа Facade и Adapter(Wrapper) решаются путем агрегирования или закрытого наследования, а полученный класс также не предназначен для наследования Добавлено через 2 минуты и 27 секунд ща поглядел, и вижу, что нет: стек агрегирует контейнер. а мне казалось я где-то видел закрытое наследование... |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
перенесено
Abyx, автор оффтопика уже создал отдельную тему... Это сообщение отредактировал(а) mes - 17.2.2011, 19:48 |
|||
|
||||
| Abyx |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 601 Регистрация: 3.11.2009 Репутация: 1 Всего: 10 |
||||
|
||||
| alexvs11 |
|
|||
|
hell is here ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 21.8.2010 Репутация: 6 Всего: 10 |
||||
|
||||
| ValeryLaptev |
|
|||
|
Препод Профиль Группа: Участник Сообщений: 41 Регистрация: 19.8.2010 Где: Астрахань Репутация: нет Всего: 1 |
Не рекомендуется наследовать, так как в стандартных контейнерах деструктор НЕ ЯВЛЯЕТСЯ ВИРТУАЛЬНЫМ. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Если только это, то это вообще не причина НЕ наследовать, это причина не удалять объект через указатель на базовый класс. Для ясности: я не согласен с тем, что класс, который наследуется обязан иметь виртуальный деструктор. Я считаю, что класс, который имеет хоть одну виртуальную функцию, должен иметь виртуальный деструктор. Остальное должно решаться в зависимости от ситуации. И кстати обсуждение переехало сюда. Это сообщение отредактировал(а) azesmcar - 20.2.2011, 12:46 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |