- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
QVector<int> v1;
v1.push_back(1);
v1.push_back(2);
// взяли итератор на нулевой элемент вектора v1
QVector<int>::iterator it = v1.begin();
// замутили копию
QVector<int> v2 = v1;
v1[1] = 42;
*it = 5;
v2[1] = 100500;
// и что же мы получим?
qDebug() << v1; // QVector(1, 42)
qDebug() << v2; // QVector(5, 100500)
Ловим лулзы с implicit sharing'ом.
Мораль (она описана в доке): нельзя копировать implicit shared контейнер пока живы и используются неконстантные итераторы на его элементы.
Все остальные ошибки они и с stl векторами вылезут. Попортил контейнер во время работы итераторов - ССЗБ (ну разве что кроме std::map'а). Дал доступ к одному инстансу контейнера двум потокам - ССЗБ (к разным инстансам с одним shared блоком можно, все будет норм).
А если в этот момент, когда делается копия в соседнем треде, произойдет запись в оригинал?
Все будет норм, т.к. счетчик ссылок декрементят после копирования (см. вырезки из кода в соседнем треде). Тот, кто пишет в оригинал замутит себе копию и насрет в нее. А оригинальный блок данных после завершения копирований умрет от одиночества.
- два треда имели разные инстансы QVector'а с одним shared блоком
- первый тред захотел что-то записать в вектор, вошел в detach() и начал копирование
- в это время второй тред через STL итератор поменял что-то в оригинале
- кровь-кишки-распидорасило
Эта проблема, как я уже неоднократно писал в этом треде, возникает только в одном случае - если ты сделал копирование контейнера при живых итераторах. Если же ты сначала расшарил контейнер, а потом получаешь итератор, то begin() сделает detach() и все будет норм.
P.S. Вот замутили бы они clone() для твоего случая - и никакой проблемы бы не было.
В сраных жабах во всех дефолтных коллекциях (непотокобезопасных) обычно из итератора кидается ConcurentModificationException, не для контроля, а скорее для того чтобы не использовали их там где не следует.
Я хз. Должно выглядеть как-то так. Это не я писал, но у нас юзается в проекте "операция подергивание или UB". Я как бы хз как правильно.
До - можно. И после того, как закончишь юзать итератор - можно. Пусть там хоть 10 потоков потом его дрочат, никаких проблем не случится.
P.S. Там кстати detach() в паблике, просто недокументированный. Это я так, к слову, не надо его юзать.
Интересно как будет разрулена сия проблема в TBVector
> И вообще считаю итератор одноразовым объектом
+1. С осторожностью поюзал внутри функции и выбросил. Хранить итераторы - ССЗБ (ну разве что они в привате вместе с контейнером).
В жабе для этих целей придумали Spliterator.
http://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html#CONCURRENT
Хранить же итератор глобально или копировать имхо какое-то безумие.
Но там не лисп и не кложура.
Херню сказал. Иногда например нужно вставить рядом с каким-то элементом. По этой причине итератор нужен. Тот же указатель понятное дело не подойдет в таком случае. А каждый раз искать по элементу его положение в коллекции - верх идеотизма
Я знаю. Но я не силен в юзерскриптах. А без них такое особого смысла нету писать, т.к. лень тыкать каждый раз в букмарклет.
http://shitstream.ru/
Еще с аяксом разобраться, да с закрытием плашек по отведению мыши, и можно альфатестить.
Респект таким парнямА у меня что-то апатия какая-то образовалась, даже кодить лень.
Глянь на двачах же.
Я, когда GK parent comment изменял, решил посмотреть, но в итоге сделал просто удаление всплывающего комментария через N миллисекунд, отмену удаления, если мышь перешла на комментарий, удаление через N миллисекунд, если мышь ушла.
Вот эта логика меня затралела, поскольку я не сидел и не сижу на имиджбордах.
P.S. Является говном, т.к. задваивает комменты при повторном запуске.
Почему не "въебал плюс"?
Вероятно, тут это чаще пишут.
А вообще, должен же быть какой-то враг/оппонент, с которым надо спорить, ради утопления которого писать боты, фильтровать его юзерскриптами и т.д.
Бой с тенью.
Там console.log вроде бы отображается
Только вот при ошибке вываливается текст всего скрипта и текст ошибки :(
Им и дебажился.
> А вообще, вали в хром + tampermonkey, там скрипты можно отлаживать.
Там прям нормальный отладчик, такой же как для остального жс?
> дебажился.
Лол
Прям нормальный.
Это когда? И зачем? Лично я стараюсь практически никогда не мутировать коллекцию итератором. Единожды написал такое, и то была говнооптимизация и хак, которого можно было избежать.
Если Вас что-то не устраивает - покиньте сайт.
Да итератор это и есть указатель, просто обобщенный на случай непотребщины, в которой элементы лежат не подряд единым блоком. Практически все проблемы указателей автоматом переходят и на итераторы, а на деле еще и новые добавляются.
И обращаться с ними надо именно так, как ты обращаешься с голыми указателями.
> Херню сказал.
Нифига не херню. Такой итератор должен лежать рядом с контейнером, в который он указывает. Причем и то и другое должно лежать в привате, чтобы не дай бог между ними рассинхрон не произошел. А глобальный итератор, ссылающийся в хуй знает куда это риалли безумие.
Чтоэта?
> Хранить итераторы - ССЗБ (ну разве что они в привате вместе с контейнером)
За что такая нелюбовь к stl-итераторам? Незаменимая же вещь. Примеры:
1. LRU-кэш на итераторах std::list
2. У меня в поисковике сортированный список документов представлен парой константных итераторов, указывающих на участок иммутабельного индекса. Пару можно прекрасно сплиттить для параллельной обработки. Хотя с этим также неплохо справляются slice-ы в Go-версии.
Это не не любовь, а осторожность. Я же нигде не писал, что я ими не пользуюсь и другим не советую... Просто они настолько же опасны/безопасны, насколько и самые обычные указатели.
> 1. LRU-кэш на итераторах std::list
Ну вот mCacheList и mCacheMap надо засунуть в приват какому-нибудь классу, иначе кто-нибудь обязательно порушит инвариант (тут проблема более общая, без итераторов я бы тоже это сделал).
> иммутабельного
Ключевое слово ;) Отдавать куда попало итератор на мутабельную коллекцию я бы не рисковал.
Just as designed. Итераторы и были спроектированы, чтобы моделировать абстрактный указатель. Даже нотацию сохранили, чтобы их не отличить было. Сишники вон таскают всюду указатели и не жалуются.
Я не предлагаю совать итераторы во все дыры, особенно с учётом с++11 с его range-based for. Концепция Range мне всегда нравилась больше. Но и итераторы весьма полезны и универсальны.
>Ключевое слово ;)
Истинно. Выше же писал что итератору в 90% случаев необходимо и достаточно быть read-only. Глобальный итератор мутирующий коллекцию - неиссякаемый источник гейзенбагов.
При этом ни о каких блокировках на итераторе естественно речи не идёт.