2016-03-24 1 views
0

J'essaie de lire les données d'un fichier dans un tableau struct struct, la taille du tableau étant étendue via realloc pour prendre en compte des données supplémentaires.Segfault lors de la lecture des données du fichier pour réallouer le tableau struct struct

Il semble fonctionner pour une seule ligne de données (taille de tableau 1), mais rien de plus gros et je reçois un segfault. Je suis assez inexpérimenté au codage, donc je suis complètement perdu sur ce qui le cause.

Voici le code correspondant:

#include <stdio.h> 
#include <stdlib.h> 

typedef struct 
{ 
    int a; 
    int b; 
} Structure; 

void Tester(Structure **Data) 
{ 
    Structure Input; size_t Number = 0; 

    *Data = NULL; 

    FILE *File = fopen("file.txt", "r"); 

    while(2 == fscanf(File, "%d %d", &Input.a, &Input.b)) 
    { 
     printf("Before: %d\n",Number); 

     Number++; 

     Structure *NewInput = realloc(*Data, Number * sizeof(Structure)); 

     *Data = NewInput; 

     printf("After: %d\n",Number); 

     *Data[Number - 1] = Input; 
    } 

    fclose(File); 
} 

int main() 
{ 
    Structure *TestData; 

    Tester(&TestData); 

    printf("%d %d", TestData[0].a, TestData[0].b); 

    return 0; 
} 

Le fichier texte que j'ai utilisé ne contenait que « 1 2 » lorsque le programme a fonctionné, et « 1 2 3 4 » quand il ne l'a pas. Les occours d'erreur à la ligne:

 *Data[Number - 1] = Input; 

Je le sentiment que le realloc ne fonctionne pas correctement après la première boucle. Toute aide ou conseil sera grandement apprécié!

+1

Les opérateurs de postfixe ont une priorité plus élevée que les opérateurs unaires. Utilisez '(* Data) [Number - 1] = Input;'. – EOF

+0

@EOF Postez la réponse – Barmar

+0

Vous devriez vérifier si 'fopen()' a réussi. – MikeCAT

Répondre

1

En raison de la priorité des opérateurs

*Data[Number - 1] = Input; 

est équivalent à

*(Data[Number - 1]) = Input; 

Cette traite Data comme un tableau de pointeurs, quand il est en fait un seul pointeur vers un autre pointeur qui pointe vers un tableau de Structure. Il utilise ensuite le Nième élément de ce tableau (qui n'existe pas réellement) comme emplacement pour copier Input vers. Il échoue quand Number > 0 car aucun de ces autres pointeurs n'a été initialisé (puisqu'il n'y a aucun tableau réel là).

La syntaxe correcte est:

(*Data)[Number - 1] = Input; 

Ce déréférence Data pour se rendre à l'ensemble des éléments Structure que vous pouvez attribuer à.

+0

Pourquoi cette réponse a-t-elle été refusée? – immibis

+0

@immibis Je pense que c'était EOF, voir notre "discussion" dans les commentaires à la réponse de MikeCat. – Barmar

+0

À l'origine, j'ai rejeté cette réponse, mais par déférence pour le fait que cela soit très opiniâtre, je l'ai supprimé. – Barmar

0

*Data[Number - 1] est équivalent à Data[Number - 1][0] parce que l'opérateur [] a la priorité plus élevée que unaire opérateur * et a[b] est équivalent à *((a) + (b)), de sorte *Data[Number - 1] = *(Data[Number - 1]) = *((Data[Number - 1]) + (0)) = [Data[Number - 1][0]

En outre, Data[1] ou au-dessus est hors de portée et il ne doit pas être accessible.

Je suppose que vous voulez (*Data)[Number - 1], ce qui équivaut à Data[0][Number - 1].

+0

Je pense qu'il serait moins déroutant si vous disiez que c'est équivalent à '* (Data [Number - 1])' – Barmar

+0

Je ne sais pas pourquoi vous l'écrivez comme 'Data [0] [Number - 1]', puisque 'Data' n'est pas utilisé comme un tableau, c'est un pointeur vers un tableau. – Barmar

+0

@Barmar Il n'y a pas de tableau ici. – EOF