разыменование только что вставленного значения std::map иногда приводит к нарушению прав доступа

Label_Info — это просто тривиальный класс с некоторыми членами типа int:

class Label_Info {
public:
    Label_Info();
    unsigned int x, x1, x2, y, y1, y2, size;
};

Label_Info::Label_Info() {
    this->x = this->y = this->size = 0;
    this->x1 = this->y1 = -1;
    this->x2 = this->y2 = 0;
}

Затем, скомпилированный с помощью gcc:

std::map<unsigned int, Label_Info> labels_info;
unsigned int label = 1;
Label_Info *label_info = &labels_info[label];

Очень редко меня останавливает нарушение прав доступа на третьей строке. Насколько я понимаю, происходит то, что std::map вставляет новую Label_Info для ключа 1, а затем указатель на это label_info. Затем (по крайней мере, когда он не падает!) Я могу получить доступ к членам следующим образом:

label_info->x = 25;

... и так далее. Я не получаю нарушения прав доступа, возможно, для 1 000 000 вставок, а затем внезапно бац. Я проверил обычные подозреваемые: 32-битный порог и нехватка памяти, и все выглядит нормально на вставке, когда она детонирует. Я знаю, что это вставка, потому что я вижу, как она проходит через этот код STL std::map в отладчике, но я не могу прочитать его достаточно хорошо, чтобы сказать, к чему он пытается получить доступ для вставки.

Так является ли этот код плохой новостью? Будем признательны за любую информацию от людей, которые знают о C++ больше, чем я. Спасибо.


person njahnke    schedule 17.05.2012    source источник
comment
Воспроизведите задачу в виде небольшой полной программы. Также рассмотрите возможность использования ссылки вместо переустанавливаемого указателя. Скорее всего, проблема связана с переустановкой указателя в коде, который здесь не показан.   -  person Cheers and hth. - Alf    schedule 17.05.2012
comment
Это в многопоточной среде?   -  person walrii    schedule 17.05.2012


Ответы (1)


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

Если вы можете скомпилировать свою кодовую базу в Linux, есть большая вероятность, что valgrind сможет найти для вас ошибку памяти.

person Mark B    schedule 17.05.2012
comment
Да, в очень редком случае я писал за пределами выделения кучи в несвязанном коде. - person njahnke; 25.05.2012