#objective-c #ios #compiler-construction #exc-bad-access #llvm-gcc
#objective-c #iOS #компилятор-конструирование #исключение-bad-access #llvm-gcc
Вопрос:
Приведенный ниже код отлично работает на GCC 4.2, но завершается ошибкой с EXC_BAD_ACCESS в LLVM GCC 4.2
- (double_t)readDouble {
double_t *dt = (double_t *)(buffer offset);
double_t ret = *dt; // Program received signal: EXC_BAD_ACCESS
offset = 8;
return ret;
}
Вот как я распределяю
int dataLength = [data length];
buffer = malloc(dataLength 1);
buffer[dataLength] = 0; // null terminate to log
[data getBytes:(void *)buffer length:[data length]];
//NSLog(@"%s", buffer);
Смещение и буфер похожи
@interface PRDataSet : NSObject {
NSMutableArray *tables;
NSMutableDictionary *tablesByName;
NSMutableDictionary *tablesById;
@private
NSURLConnection *conn;
int offset;
char *buffer;
}
Да, смещение находится в пределах диапазона.
Я не освобождаю буфер перед его использованием.
Есть идеи?
Ответ №1:
Это может быть проблемой с настройкой. Процессоры ARM (и многие другие процессоры) имеют ограничения в отношении выравнивания данных, например, они могут считывать и записывать числа с плавающей запятой только с адресов, кратных 4 или 8.
Судя по тому, как буфер выделен в вашем коде, он может быть выделен неправильно, или ваши double_t
элементы данных не выровнены внутри буфера.
Чтобы избежать проблемы, вы должны попытаться сначала скопировать данные в выровненный буфер и прочитать их оттуда.
Комментарии:
1. Вы правы. Речь идет о выравнивании с плавающей запятой. Мой буфер настроен из разных типов данных, поэтому я не смог выровнять буфер. Решение заключается в чтении как целого числа, а затем приведении к числам с плавающей запятой. Я думаю, что это то, что сделал GCC. LLVM не выполняет это исправление, но я думаю, что это должно произойти в будущем. Разработчикам не обязательно знать ограничения процессора. Для этого и существуют компиляторы.
Ответ №2:
LLVM просто не считывает float напрямую.
Вот решение:
- (uint32_t)readUInt32 {
uint32_t ret = *(uint32_t *)(buffer offset);
offset = 4;
return ret;
}
- (uint16_t)readUInt16 {
uint16_t ret = *(uint16_t *)(buffer offset);
offset = 2;
return ret;
}
- (uint64_t)readUInt64 {
uint64_t ret = *(uint64_t *)(buffer offset);
offset = 8;
return ret;
}
- (float_t)readSingle {
uint32_t t = [self readUInt32];
float_t ret = *((float_t *)(amp;t));
return ret;
}
- (double_t)readDouble {
uint64_t t = [self readUInt64];
double_t ret = *((double_t *)(amp;t));
return ret;
}