0

下面的代碼運行在GCC 4.2得很好,但未能與EXC_BAD_ACCESS在LLVM GCC 4.2LLVM 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

這可能是一個問題。 ARM處理器(和許多其他處理器)在數據對齊方面有限制,例如,它們只能從4或8的倍數的地址讀寫浮點數。

從代碼中分配緩衝區的方式來看,它可能沒有正確分配,或者您的數據元素不是正確的, t在緩衝區內對齊。

爲了避免這個問題,您應該先嚐試將數據複製到一個對齊的緩衝區並從那裏讀取。

+0

你是對的。它關於浮點對齊。我的緩衝區是從不同的數據類型設置的,所以我無法對齊緩衝區。解決方法是讀取整數,然後轉換爲浮點數。我認爲這就是GCC所做的。 LLVM不會做這種修正,但我認爲它應該在未來。開發人員不需要知道處理器限制。這是編譯器的目的。 – 2011-05-21 13:45:51

1

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

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