2009-10-21 4 views
2

Utilisation de WindowsQu'est-ce qui pourrait provoquer un programme Labwindows/CVI C à détester le numéro 2573?

Je lis donc à partir d'un fichier binaire une liste de valeurs de données int non signées. Le fichier contient un certain nombre d'ensembles de données répertoriés séquentiellement. Voici la fonction de lire un seul jeu de données à partir d'un char * pointant vers le début de celui-ci:

function read_dataset(char* stream, t_dataset *dataset){ 

    //...some init, including setting dataset->size; 

    for(i=0;i<dataset->size;i++){ 
     dataset->samples[i] = *((unsigned int *) stream); 
     stream += sizeof(unsigned int); 
    } 
    //... 
} 

Où read_dataset dans un tel contexte que cela:

//... 
char buff[10000]; 
t_dataset* dataset = malloc(sizeof(*dataset)); 
unsigned long offset = 0; 

for(i=0;i<number_of_datasets; i++){ 

    fseek(fd_in, offset, SEEK_SET); 

    if((n = fread(buff, sizeof(char), sizeof(*dataset), fd_in)) != sizeof(*dataset)){ 
     break; 
    } 

    read_dataset(buff, *dataset); 

    // Do something with dataset here. It's screwed up before this, I checked. 


    offset += profileSize; 
} 
//... 

Tout se passe à merveille jusqu'à ce que ma boucle lit la Numéro 2573. Tout à coup, il commence à cracher des nombres aléatoires et énormes.

Par exemple, ce qui devrait être

... 
1831 
2229 
2406 
2637 
2609 
2573 
2523 
2247 
... 

devient

... 
1831 
2229 
2406 
2637 
2609 
0xDB00000A 
0xC7000009 
0xB2000008 
... 

Si vous pensez que ces chiffres hexagonaux semblent suspectes, vous avez raison. Active les valeurs hexagonales pour les valeurs qui ont été modifiées sont vraiment familiers:

2573 -> 0xA0D 
2523 -> 0x9DB 
2247 -> 0x8C7 

Donc, apparemment ce nombre 2573 provoque mon pointeur de flux pour obtenir un octet. Cela reste jusqu'à ce que l'ensemble de données suivant soit chargé et analysé, et que Dieu m'en interdise le numéro 2573. J'ai vérifié un certain nombre d'endroits où cela se produit, et chacun d'eux a commencé sur 2573.

Je ne suis pas si talentueux dans le monde de C. Ce qui pourrait causer cela est complètement et entièrement opaque pour moi.

Répondre

11

Vous ne spécifiez pas comment vous avez obtenu les octets en mémoire (pointés par flux), ni quelle plate-forme vous utilisez, mais je ne serais pas surpris de trouver votre sur Windows, et vous avez utilisé l'appel de la bibliothèque C stdio fopen(filename "r"); Essayez d'utiliser fopen(filename, "rb");. Sur Windows (et MS-DOS), fopen() traduit les fins de ligne MS-DOS "\ r \ n" (hex 0x0D 0x0A) dans le fichier au format Unix "\ n", sauf si vous ajoutez "b" au mode fichier pour indiquer binaire.

+0

Bon endroit (et bien fait - afin de faire à 15 caractères!) –

+0

Merci monsieur, je comprends l'erreur de mes façons (et oui, j'ai oublié le "b"). –

+0

J'avais l'habitude d'oublier occasionnellement le "b", et reconnu les symptômes. –

0

Quelques points non pertinents.

sizeof (* dataset) ne fait pas ce que vous pensez qu'il fait.

Il n'y a pas besoin d'utiliser tous les chercher à lire

Je ne comprends pas comment vous appelez une fonction qui prend un seul paramètre, mais vous lui donnez deux (ou du moins je ne comprends pas pourquoi votre compilateur ne s'y oppose pas)

+0

Je suis peut-être bouche bée, mais j'ai laissé certaines choses hors de mon code. Chaque jeu de données contient un petit en-tête qui indique le nombre d'échantillons, ce qui n'est pas cohérent entre les fichiers. Par conséquent, t_dataset est la taille du plus grand ensemble de données que je prévois rencontrer. C'est probablement faux, mais pour ma défense, je n'ai pas écrit cela. Ainsi, fseek compense le dépassement. –

Questions connexes