Подтвердить что ты не робот

Таинственное поведение unordered_map в Visual Studio

Я хочу хранить значения ~ 3 000 000 double в unsigned int индексах под VS2010 С++. Для этой цели я использую std::tr1:unordered_map<unsigned int, double>. К сожалению, когда я пытаюсь сохранить значение числа 2 ^ 21, генерируется исключение (как будто есть только пространство для 2 ^ 21-1, то есть какой-то индекс может использовать только 20 бит). Я попытался rehash перед сохранением значений, которые также не работали.

Наконец, я закончил с очень простой тестовой программой (которая показала даже немного другое поведение, но в любом случае):

    std::tr1::unordered_map<unsigned int, float> mapOut;
    //mapOut.rehash(SOMESIZE);
    for (unsigned int i=0; i<3000000; i++)
    {
        if (i%1000==0) std::cout << i << std::endl;
        mapOut[i] = 0.0;
    }

В некоторых случаях я проверил:

1) Если я вообще не перефразирую, программа выполняет длинный перерыв после выхода в соответствии с i == 32000 (в конечном итоге 2 ^ 15), а затем продолжает i == 262000 (2 ^ 18). Там он хранится вечно (при 100% загрузке процессора, память не увеличивается).

2) Если я делаю a rehash(1000), он приходит к i == 65000 (2 ^ 16) и сохраняется навсегда (загрузка процессора 100%, память не увеличивается).

3) Если я делаю a rehash(3000000), цикл успешно завершен, но программа никогда не выйдет - то есть, очевидно, что есть некоторая проблема с деструктором.

Что там происходит и что еще важнее: что мне делать?

Большое спасибо за вашу помощь!

4b9b3361

Ответ 1

Следующая ошибка в соединении связана с вашей проблемой: Visual С++: std:: unordered_map Производительность деструктора в конфигурации отладки

Такая же проблема возникает не только в деструкторе, но также и при изменении размера unordered_map. Кажется, что есть что-то с недействительными итераторами, если включена отладка итератора.

Говорят, что он был исправлен для VC11. Существует также несколько обходных решений, но я их не пробовал.

Очень простой способ решить проблему с производительностью как для сборки отладки, так и для выпуска - установить _SECURE_SCL=0 и _HAS_ITERATOR_DEBUGGING=0 в параметрах проекта в разделе "Параметры конфигурации/C/С++/Препроцессор/Препроцессоры", который полностью отключает все отладки итератора. Однако это также отключает некоторые проверки безопасности, поэтому вам нужно быть более осторожными в своем собственном коде. Я считаю, что оба эти значения по умолчанию уже выпущены, поэтому вам не нужно ничего менять.

Это, как представляется, связано с проблемой вашего образца кода. Я не уверен в исходной проблеме, так как вы не сказали, какое исключение было брошено.