2016-03-24 5 views
0

Ich versuche, Daten aus einer Datei in ein dynamisches Struct-Array zu lesen, wobei die Array-Größe über Realloc erweitert wird, um zusätzliche Daten aufzunehmen.Segfault beim Lesen von Daten aus der Datei zum erneuten Zuweisen dynamischer Struct-Arrays

Es scheint für eine einzelne Zeile von Daten (Array-Größe 1) zu funktionieren, aber alles größer und ich bekomme einen segfault. Ich bin ziemlich unerfahren im Codieren, also bin ich völlig verloren in dem, was es verursacht. Hier

ist der entsprechende Code:

#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; 
} 

Die Textdatei, die wir enthalten ist, verwenden nur ‚1 2‘, wenn das Programm gearbeitet, und ‚1 2 3 4‘, wenn es nicht. Die Fehler occours an der Linie:

 *Data[Number - 1] = Input; 

So habe ich das Gefühl, dass der realloc nicht richtig nach der ersten Schleife arbeitet. Jede Hilfe oder Beratung wird sehr geschätzt!

+1

Postfix-Operatoren haben höhere Priorität als unäre Operatoren. Verwenden Sie '(* Data) [Number - 1] = Input;'. – EOF

+0

@EOF Post es als Antwort – Barmar

+0

Sie sollten überprüfen, ob 'fopen()' erfolgreich war. – MikeCAT

Antwort

1

Wegen Operator Vorrang

*Data[Number - 1] = Input; 

entspricht

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

Diese Data als Array von Zeigern behandelt, wenn es tatsächlich ein einzelner Zeiger auf einen anderen Zeiger, der auf ein Array verweist von Structure. Es verwendet dann das N-te Element dieses Arrays (welches nicht wirklich existiert) als den zu kopierenden Ort Input. Es schlägt fehl, wenn Number > 0 da keiner dieser anderen Zeiger initialisiert worden ist (da dort kein tatsächliches Array ist).

Die korrekte Syntax ist:

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

Diese dereferenziert Data an die Anordnung von Structure Elemente zu erhalten, die Sie zuordnen können.

+0

Warum wurde diese Antwort abgelehnt? – immibis

+0

@immibis Ich denke, es war EOF, siehe unsere "Diskussion" in den Kommentaren zu MikeCat's Antwort. – Barmar

+0

Ich habe diese Antwort ursprünglich abgelehnt, aber aus Rücksicht auf die Tatsache, dass dies sehr eigensinnig ist, habe ich es entfernt. – Barmar

0

*Data[Number - 1] entspricht Data[Number - 1][0] weil [] Betreiber höhere Priorität hat als unären * Operator und a[b] entspricht *((a) + (b)), so *Data[Number - 1] = *(Data[Number - 1]) = *((Data[Number - 1]) + (0)) = [Data[Number - 1][0]

Auch Data[1] oder darüber außerhalb des Bereichs liegt, und Es darf nicht zugegriffen werden.

Ich denke, Sie möchten (*Data)[Number - 1], die Data[0][Number - 1] entspricht.

+0

Ich denke, es wäre weniger verwirrend, wenn Sie sagten, es ist gleichbedeutend mit '* (Data [Number - 1])' – Barmar

+0

Ich bin mir nicht sicher, warum Sie es als 'Data [0] [Number - 1]', da schreiben würde 'Data' wird nicht als Array verwendet, es ist ein Zeiger auf ein Array. – Barmar

+0

@Barmar Es gibt kein Array hier. – EOF

Verwandte Themen