LLVM GCC 4.2 EXC_BAD_ACCESS

时间:2011-05-20 13:50:11

标签: objective-c ios compiler-construction exc-bad-access llvm-gcc

下面的代码在GCC 4.2上运行正常,但在LLVM GCC 4.2中使用EXC_BAD_ACCESS失败

- (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;

}

是偏移在范围内。 在使用之前我没有释放缓冲区。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

这可能是一个对话问题。 ARM处理器(以及许多其他处理器)对数据对齐有限制,例如,它们只能从4或8的倍数地址读取和写入浮点数。

从代码中分配缓冲区的方式来看,可能没有正确分配缓冲区,或者您的double_t数据元素未在缓冲区内对齐。

为了避免这个问题,你应该先尝试将数据复制到对齐的缓冲区并从那里读取。

答案 1 :(得分:1)

LLVM只是不直接读取浮点数。

以下是解决方案:

- (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 *)(&t));
    return ret;
}

- (double_t)readDouble  {
    uint64_t t = [self readUInt64];
    double_t ret = *((double_t *)(&t));
    return ret;
}