LLVM GCC 4.2 EXC_BAD_ACCESS

问题描述 投票:0回答:2

下面的代码在 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;

}

是的,偏移量在范围内。 在使用缓冲区之前我不会释放它。

有什么想法吗?

ios objective-c exc-bad-access llvm-gcc
2个回答
2
投票

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

从代码中分配缓冲区的方式来看,它可能未正确分配,或者您的

double_t
数据元素在缓冲区内未对齐。

为了避免出现此问题,您应该尝试首先将数据复制到对齐的缓冲区中,然后从那里读取数据。


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.