0

Ci-dessous le code fonctionne très bien sur GCC 4.2, mais échoue avec EXC_BAD_ACCESS dans 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; 
} 

Voilà comment j'allouer

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

Offset et le tampon est comme

@interface PRDataSet : NSObject { 

    NSMutableArray *tables; 
    NSMutableDictionary *tablesByName; 
    NSMutableDictionary *tablesById; 

@private 
    NSURLConnection *conn; 
    int offset; 
    char *buffer; 

} 

Oui le décalage est dans la plage. Je ne libère pas le tampon avant de l'utiliser.

Des idées?

Répondre

2

Cela pourrait être un problème d'aligment. Les processeurs ARM (et de nombreux autres processeurs) ont des restrictions concernant l'alignement des données, par ex. ils peuvent seulement lire et écrire des nombres à virgule flottante à partir d'adresses qui sont un multiple de 4 ou 8.

De la façon dont le tampon est alloué dans votre code, il peut ne pas être alloué correctement, ou vos éléments de données double_t ne sont pas ' t aligné dans le tampon. Pour éviter le problème, vous devez d'abord copier les données dans un tampon aligné et les lire à partir de là.

+0

Vous avez raison. Il s'agit de l'alignement en virgule flottante. Mon tampon est configuré à partir de différents types de données, donc je n'ai pas pu aligner le tampon. La solution lit un nombre entier, puis les convertit en nombres à virgule flottante. Je pense que c'est ce que GCC a fait. LLVM ne fait pas cette correction mais je pense que cela devrait être le cas dans le futur. Les développeurs n'ont pas besoin de connaître les restrictions du processeur. C'est ce que les compilateurs sont pour. –

1

LLVM ne lit pas directement le flottant.

est ici la solution:

- (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; 
} 
Questions connexes