У вас проблема с выравниванием данных. Вероятно, это вызвано попыткой чтения или записи через неверный указатель.
Проблема выравнивания данных возникает, когда адрес, на который указывает указатель, не «выровнен» должным образом. Например, некоторые архитектуры (например, старый Cray 2) требуют, чтобы любая попытка чтения из памяти чего-либо, кроме одного символа, происходила только через указатель, в котором последние 3 бита значения указателя равны 0. Если какой-либо из последних 3 бита равны 1, аппаратное обеспечение сгенерирует ошибку выравнивания, что приведет к проблеме, которую вы видите.
Большинство архитектур далеко не так строги, и часто требуемое выравнивание зависит от конкретного типа, к которому осуществляется доступ. Например, для 32-битного целого числа может потребоваться, чтобы только последние 2 бита указателя были равны 0, а для 64-битного числа с плавающей запятой может потребоваться, чтобы последние 3 бита были равны 0.
Проблемы с выравниванием обычно вызываются теми же проблемами, что и SEGFAULT или ошибка сегментации. Обычно указатель, который не инициализирован. Но это может быть вызвано плохим распределителем памяти, который не возвращает указатели с правильным выравниванием, или результатом арифметических операций над указателем, когда он имеет неправильный тип.
Системная реализация malloc
и/или operator new
почти наверняка верна, иначе ваша программа рухнет раньше, чем сейчас. Поэтому я думаю, что плохой распределитель памяти — это наименее вероятное дерево, которое начнет лаять. Я бы сначала проверил неинициализированный указатель, а затем неверную арифметику указателя.
В качестве примечания: для архитектур x86 и x86_64 нет требований к выравниванию. Но из-за того, как работают строки кэша, а также по ряду других причин, для производительности часто бывает полезно выровнять ваши данные по границе, равной размеру сохраняемого типа данных (т. е. границе 4 байта для 32-битного целого числа).
14.07.2010