Программа получила сигнал EXC_BAD_ACCESS доступа к массиву - PullRequest
0 голосов
/ 19 февраля 2011

Я использую подпрограмму для получения цвета пикселя (эта: http://www.markj.net/iphone-uiimage-pixel-color/) и сталкиваюсь с частыми сбоями приложения при его использовании.Соответствующая часть кода:

unsigned char* data = CGBitmapContextGetData (cgctx);
if (data != NULL) {
    int offset = (some calculations here);
    int alpha = data[offset]; // <<<< crashes here
}

Этот код связан для запуска на элементах touchesBegan, touchesEnded и touchesMoved.Похоже, что сбои происходят только во время событий touchesEnded и touchesMoved, особенно когда я запускаю касание на целевом изображении, но в процессе перемещаю его за границы изображения.

Есть ли способ проверить, какой размер данных в массиве указан объектом data?Что может быть не так?

Редактировать : Расчет смещения:

int offset = 4*((w*round(point.y)*x)+round(point.x)*x);

Где point - точка, где происходит касание, w - ширина изображения, x - это масштаб изображения (для изображений высокого разрешения на дисплеях сетчатки).

Я тоже не вижу ничего плохого в cgctx.По сути, я запускаю код по приведенной выше ссылке почти без изменений, конкретный фрагмент кода, с которым у меня возникают проблемы, находится в функции (UIColor*) getPixelColorAtLocation:(CGPoint)point, поэтому, если вы хотите получить подробную информацию о том, что делает код, просто прочитайте исходный код.

Редактировать: другое дело, что это никогда не происходит в симуляторе, но часто происходит при тестировании на устройстве.

Редактировать: В идеале я бы хотел сделать ничего , если палецв настоящее время не над изображением, но есть проблемы с выяснением, когда это произойдет.Похоже, что соответствующие методы в SDK показывают только то, в каком виде возникло касание, а не где оно сейчас.Как я могу это выяснить?

1 Ответ

2 голосов
/ 19 февраля 2011

Вы не показали всю свою работу.Ваш расчет offset, скорее всего, вернет либо отрицательное число, либо число, выходящее далеко за пределы буфера.Поскольку API CG* часто выделяют довольно большие фрагменты памяти, часто отображаемые в память, вполне вероятно, что адреса до и после выделения являются нераспределенными / не отображенными, и, таким образом, доступ вне буфера приводит к немедленному отказу (в отличие отна возврат мусора).

Что хорошо.Проще отладить.

Вы предоставили подсказку:

переместите его за пределы изображения в процессе

Я думаю, вы изменили offset расчет, чтобы принять местоположение касания.И это местоположение вышло за границы изображения и, таким образом, приводит к бессмысленной offset и последующей аварии.

Исправьте это, и ваше приложение перестанет падать здесь.

Ваше изображение точно занимает все границы предмета, к которому прикасаются?Т.е. имеет ли объект, обрабатывающий события touches*:, границы, ширина и высота которых точно совпадают с изображением?

Если нет, вам нужно убедиться, что вы правильно переводитекоординаты от того, что обрабатывает прикосновения к координатам в изображении.Также обратите внимание, что расположение байтов в изображении сильно зависит от того, как именно было создано изображение и какая внутренняя цветовая модель используется.

...