У меня странная проблема, когда я строю один из наших проектов в 64-битной конфигурации отладки. Похоже, что это приводит к некоторому странному поведению, похожему на то, что один итератор увеличивается несколько раз. Я сузил его до следующего кода теста:
#include <omp.h>
#define _HAS_ITERATOR_DEBUGGING 0
#include <vector>
#include <set>
int main(int argc, const char* argv[]) {
std::vector<int> v;
for(int j = 0; j < 20; ++j) {
v.push_back(j);
}
#pragma omp parallel for
for(int i = 0; i < 100000; ++i) {
std::set<int> s;
std::vector<int>::const_iterator begin = v.begin(), end = v.end();
s.insert(begin, end); // after this line s should contain the numbers 0-19
if(s.size() != 20) {
printf("fail\n");
exit(3);
}
}
return 0;
}
Тем не менее, проверка размера часто дает сбой, что подразумевает, что каким-то образом он не вставляет все содержимое вектора - и из-за большого количества попыток он выглядит так, как будто итераторы вектора увеличиваются более чем на один шаг за раз , Это довольно сложно сказать, так как этого не случится, если кто-нибудь взломает отладчик.
Очевидный вывод, который можно сделать, состоит в том, что он не является потокобезопасным, но, насколько я понимаю, так и должно быть, потому что единственная измененная переменная - это s
, которая имеет локальную область видимости.
Есть несколько вещей, которые решат насущную проблему:
- удалить параллель для
- бросить критическую секцию вокруг
insert()
вызова
#define HAS_ITERATOR_DEBUGGING 1
- замените одиночный вызов insert () на ручной цикл и вставьте каждый элемент по отдельности (это в основном то, что эта функция выполняет внутри, но проблема определенно исчезает, когда я делаю это сам)
- сборка 32-битной версии того же кода
- сборка релизной версии с тем же кодом
Это компилируется под MSVC ++ 2008 SP1, с предоставленной компилятором реализацией STL.
Может кто-нибудь пролить свет на то, что здесь происходит? Заранее спасибо за любые подсказки - я довольно озадачен:)
Редактировать: Если неясно, я не ищу "быстрое исправление", чтобы этот код работал; как отмечалось выше, я знаю довольно много из них. Я хочу понять, почему эта проблема возникает в первую очередь.
Редактировать 2: Код работает правильно при компиляции с gcc.