- 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 контейнер пока живы и используются неконстантные итераторы на его элементы.
bormand 06.05.2014 19:06 # −1
hometwo 06.05.2014 19:10 # −6
bormand 06.05.2014 19:23 # −3
hometwo 06.05.2014 20:23 # −4
brutushafens 06.05.2014 20:27 # −3
roman-kashitsyn 06.05.2014 19:12 # +5
bormand 06.05.2014 19:17 # 0
LispGovno 06.05.2014 19:22 # −1
roman-kashitsyn 06.05.2014 19:25 # +2
3.14159265 06.05.2014 20:24 # −1
hometwo 06.05.2014 20:28 # −8
bormand 06.05.2014 20:32 # −1
brutushafens 06.05.2014 20:32 # −4
hometwo 06.05.2014 21:46 # −7
bormand 06.05.2014 19:38 # −2
Все остальные ошибки они и с stl векторами вылезут. Попортил контейнер во время работы итераторов - ССЗБ (ну разве что кроме std::map'а). Дал доступ к одному инстансу контейнера двум потокам - ССЗБ (к разным инстансам с одним shared блоком можно, все будет норм).
roman-kashitsyn 06.05.2014 19:24 # −1
bormand 06.05.2014 19:29 # −1
LispGovno 06.05.2014 19:38 # −2
А если в этот момент, когда делается копия в соседнем треде, произойдет запись в оригинал?
bormand 06.05.2014 19:40 # 0
Все будет норм, т.к. счетчик ссылок декрементят после копирования (см. вырезки из кода в соседнем треде). Тот, кто пишет в оригинал замутит себе копию и насрет в нее. А оригинальный блок данных после завершения копирований умрет от одиночества.
LispGovno 06.05.2014 19:49 # 0
bormand 06.05.2014 20:07 # −1
- два треда имели разные инстансы QVector'а с одним shared блоком
- первый тред захотел что-то записать в вектор, вошел в detach() и начал копирование
- в это время второй тред через STL итератор поменял что-то в оригинале
- кровь-кишки-распидорасило
Эта проблема, как я уже неоднократно писал в этом треде, возникает только в одном случае - если ты сделал копирование контейнера при живых итераторах. Если же ты сначала расшарил контейнер, а потом получаешь итератор, то begin() сделает detach() и все будет норм.
P.S. Вот замутили бы они clone() для твоего случая - и никакой проблемы бы не было.
3.14159265 06.05.2014 20:27 # +3
В сраных жабах во всех дефолтных коллекциях (непотокобезопасных) обычно из итератора кидается ConcurentModificationException, не для контроля, а скорее для того чтобы не использовали их там где не следует.
bormand 06.05.2014 20:10 # −1
LispGovno 06.05.2014 19:25 # 0
Я хз. Должно выглядеть как-то так. Это не я писал, но у нас юзается в проекте "операция подергивание или UB". Я как бы хз как правильно.
bormand 06.05.2014 19:27 # −2
До - можно. И после того, как закончишь юзать итератор - можно. Пусть там хоть 10 потоков потом его дрочат, никаких проблем не случится.
LispGovno 06.05.2014 19:29 # 0
bormand 06.05.2014 19:30 # 0
P.S. Там кстати detach() в паблике, просто недокументированный. Это я так, к слову, не надо его юзать.
LispGovno 06.05.2014 19:31 # 0
LispGovno 06.05.2014 19:34 # 0
3.14159265 06.05.2014 20:22 # +4
Интересно как будет разрулена сия проблема в TBVector
bormand 06.05.2014 20:31 # 0
> И вообще считаю итератор одноразовым объектом
+1. С осторожностью поюзал внутри функции и выбросил. Хранить итераторы - ССЗБ (ну разве что они в привате вместе с контейнером).
3.14159265 06.05.2014 20:45 # +2
В жабе для этих целей придумали Spliterator.
http://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html#CONCURRENT
Хранить же итератор глобально или копировать имхо какое-то безумие.
LispGovno 06.05.2014 20:54 # 0
3.14159265 06.05.2014 21:10 # 0
Но там не лисп и не кложура.
LispGovno 06.05.2014 20:56 # 0
Херню сказал. Иногда например нужно вставить рядом с каким-то элементом. По этой причине итератор нужен. Тот же указатель понятное дело не подойдет в таком случае. А каждый раз искать по элементу его положение в коллекции - верх идеотизма
brutushafens 06.05.2014 21:02 # +1
defecate-plusplus 06.05.2014 21:29 # +3
guest 06.05.2014 22:05 # +2
brutushafens 06.05.2014 22:09 # +2
Lure Of Chaos 08.05.2014 20:03 # +2
bormand 08.05.2014 20:06 # 0
eth0 08.05.2014 20:49 # 0
bormand 08.05.2014 20:54 # 0
eth0 08.05.2014 21:06 # 0
bormand 08.05.2014 21:10 # +3
guest 08.05.2014 21:12 # +2
bormand 08.05.2014 21:14 # +1
guest 08.05.2014 21:24 # 0
bormand 08.05.2014 21:31 # 0
Я знаю. Но я не силен в юзерскриптах. А без них такое особого смысла нету писать, т.к. лень тыкать каждый раз в букмарклет.
guest 08.05.2014 21:44 # 0
bormand 08.05.2014 23:08 # +1
WGH 08.05.2014 23:56 # 0
http://shitstream.ru/
guest 09.05.2014 02:18 # +1
bormand 09.05.2014 13:55 # +2
Еще с аяксом разобраться, да с закрытием плашек по отведению мыши, и можно альфатестить.
eth0 09.05.2014 14:46 # +2
Респект таким парнямА у меня что-то апатия какая-то образовалась, даже кодить лень.
guest 09.05.2014 18:15 # 0
Глянь на двачах же.
bormand 09.05.2014 19:07 # 0
1024-- 09.05.2014 19:13 # +1
Я, когда GK parent comment изменял, решил посмотреть, но в итоге сделал просто удаление всплывающего комментария через N миллисекунд, отмену удаления, если мышь перешла на комментарий, удаление через N миллисекунд, если мышь ушла.
bormand 09.05.2014 19:22 # 0
1024-- 09.05.2014 19:27 # +1
Вот эта логика меня затралела, поскольку я не сидел и не сижу на имиджбордах.
bormand 09.05.2014 19:31 # 0
1024-- 09.05.2014 19:33 # 0
bormand 08.05.2014 22:46 # +1
P.S. Является говном, т.к. задваивает комменты при повторном запуске.
chtulhu 09.05.2014 11:20 # +1
1024-- 09.05.2014 11:40 # +3
bormand 09.05.2014 19:02 # 0
Почему не "въебал плюс"?
1024-- 09.05.2014 19:06 # 0
Вероятно, тут это чаще пишут.
А вообще, должен же быть какой-то враг/оппонент, с которым надо спорить, ради утопления которого писать боты, фильтровать его юзерскриптами и т.д.
bormand 09.05.2014 19:08 # 0
Бой с тенью.
bormand 09.05.2014 19:09 # 0
bormand 09.05.2014 19:10 # 0
1024-- 09.05.2014 19:14 # 0
Там console.log вроде бы отображается
Только вот при ошибке вываливается текст всего скрипта и текст ошибки :(
guest 09.05.2014 19:50 # 0
bormand 09.05.2014 20:05 # 0
Им и дебажился.
> А вообще, вали в хром + tampermonkey, там скрипты можно отлаживать.
Там прям нормальный отладчик, такой же как для остального жс?
guest 09.05.2014 20:22 # 0
> дебажился.
Лол
Прям нормальный.
bormand 09.05.2014 19:11 # 0
bormand 09.05.2014 19:13 # 0
bormand 09.05.2014 19:20 # 0
bormand 09.05.2014 19:20 # 0
3.14159265 06.05.2014 21:05 # −2
Это когда? И зачем? Лично я стараюсь практически никогда не мутировать коллекцию итератором. Единожды написал такое, и то была говнооптимизация и хак, которого можно было избежать.
bormand 06.05.2014 23:15 # −1
3.14159265 06.05.2014 21:09 # +4
Если Вас что-то не устраивает - покиньте сайт.
bormand 06.05.2014 23:11 # +1
Да итератор это и есть указатель, просто обобщенный на случай непотребщины, в которой элементы лежат не подряд единым блоком. Практически все проблемы указателей автоматом переходят и на итераторы, а на деле еще и новые добавляются.
И обращаться с ними надо именно так, как ты обращаешься с голыми указателями.
> Херню сказал.
Нифига не херню. Такой итератор должен лежать рядом с контейнером, в который он указывает. Причем и то и другое должно лежать в привате, чтобы не дай бог между ними рассинхрон не произошел. А глобальный итератор, ссылающийся в хуй знает куда это риалли безумие.
guest 09.05.2014 18:19 # 0
Чтоэта?
roman-kashitsyn 08.05.2014 08:50 # 0
> Хранить итераторы - ССЗБ (ну разве что они в привате вместе с контейнером)
За что такая нелюбовь к stl-итераторам? Незаменимая же вещь. Примеры:
1. LRU-кэш на итераторах std::list
2. У меня в поисковике сортированный список документов представлен парой константных итераторов, указывающих на участок иммутабельного индекса. Пару можно прекрасно сплиттить для параллельной обработки. Хотя с этим также неплохо справляются slice-ы в Go-версии.
bormand 08.05.2014 09:00 # 0
Это не не любовь, а осторожность. Я же нигде не писал, что я ими не пользуюсь и другим не советую... Просто они настолько же опасны/безопасны, насколько и самые обычные указатели.
> 1. LRU-кэш на итераторах std::list
Ну вот mCacheList и mCacheMap надо засунуть в приват какому-нибудь классу, иначе кто-нибудь обязательно порушит инвариант (тут проблема более общая, без итераторов я бы тоже это сделал).
> иммутабельного
Ключевое слово ;) Отдавать куда попало итератор на мутабельную коллекцию я бы не рисковал.
roman-kashitsyn 08.05.2014 10:15 # +1
Just as designed. Итераторы и были спроектированы, чтобы моделировать абстрактный указатель. Даже нотацию сохранили, чтобы их не отличить было. Сишники вон таскают всюду указатели и не жалуются.
Я не предлагаю совать итераторы во все дыры, особенно с учётом с++11 с его range-based for. Концепция Range мне всегда нравилась больше. Но и итераторы весьма полезны и универсальны.
3.14159265 08.05.2014 15:25 # +1
>Ключевое слово ;)
Истинно. Выше же писал что итератору в 90% случаев необходимо и достаточно быть read-only. Глобальный итератор мутирующий коллекцию - неиссякаемый источник гейзенбагов.
При этом ни о каких блокировках на итераторе естественно речи не идёт.
guest 08.05.2014 21:28 # 0