2016-07-12 13 views
-2

Ich bin relativ neu in C und ich erstellte ein Programm, das eine verknüpfte Liste enthält. Hier ist eine sehr abgekürzte Version des Codes, der mir Probleme bereitet.C: Variable ist für verknüpfte Liste nicht initialisiert

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

#define STRLEN 100 

struct Gene { 
    int num[4]; 
    struct Gene *next; 
    }; 
typedef struct Gene item; 

void build_list(item *current, item *head, FILE *in); 

int main() { 

    FILE *input; 
    FILE *output; 
    input = fopen("test.data", "r"); 
    output = fopen("test.out", "w+"); 

    item *curr; 
    item *head; 
    head = NULL; 
    int i; 

    build_list(curr, head, input); 
    curr = head; 

    while(curr) { 
     for (i = 0; i < 4; ++i) 
      fprintf(output, "%d\n", curr->num[i]); 
     curr = curr->next; 
     } 

    fclose(input); 
    fclose(output); 
    free(curr); 
} 

void build_list(item *current, item *head, FILE *in) { 

    char gene[STRLEN]; 
    char *tok; 
    char gene_name[STRLEN]; 
    char *search = ","; 
    int j; 

    while (fgets(gene, sizeof(gene), in)) { 

     current = (item *)malloc(sizeof(item)); 
     tok = strtok(gene, search); 
     strcpy(gene_name, tok); 
     for (j = 0; j < 4; ++j) { 
      tok = strtok(NULL, search); 
      current->num[j] = atoi(tok); 
      } 
     current->next = head; 
     head = current; 
    } 
} 

Wenn ich versuche, dies zu kompilieren, heißt es variable curr nicht initialisiert ist, aber selbst wenn ich es mit malloc initialisieren wirft es einen Segmentation Fault, oder er druckt gar nichts aus. Warum könnte das sein?

+0

Sie wissen, dass 'build_list (curr, head, input)' einen nicht initialisierten Wert als ersten Parameter übergibt? – immibis

+0

'curr' und' head' werden nach Wert übergeben. –

+0

Ja, wie konnte ich das umgehen? – matnnar

Antwort

0

@Sourav Ghosh haben bereits erklärt, was mit Ihrem Code falsch war und schlug auch eine Möglichkeit vor, es zu lösen. Hier ist ein anderer Weg.

Anstatt current und head als Variablen innerhalb der Funktion (d. H. Als Zeiger auf Zeiger) zu ändern, würde ich empfehlen, dass Sie den Rückgabewert der Funktion verwenden. Auf diese Weise müssen Sie nicht Zeiger zu Zeiger verwenden.

Etwas wie:

item* add_item(item* head) 
{ 
    // Place a new item in front 
    item* current = malloc(sizeof(item)); 
    current->next = head; 
    return current; 
} 

item* build_list(item* head, FILE *in) { 

    char gene[STRLEN]; 
    char *tok; 
    char gene_name[STRLEN]; 
    char *search = ","; 
    int j; 

    while (fgets(gene, sizeof(gene), in)) 
    { 
     // Get a new item 
     head = add_item(head); 

     // Fill data into the new item 
     tok = strtok(gene, search); 
     strcpy(gene_name, tok); 
     for (j = 0; j < 4; ++j) 
     { 
      tok = strtok(NULL, search); 
      head->num[j] = atoi(tok); 
     } 
    } 

    return head; 
} 

und von main es nennen mag:

head = NULL; 
head = build_list(head, input); 

Hinweis: Zur besseren Lesbarkeit ausgelassen ich alle Kontroll malloc für versagen. In echtem Code sollten Sie immer überprüfen, ob malloc NULL zurückgibt.

2

C verwendet den Übergabewert für die Übergabe von Funktionsargumenten. Wenn Sie also build_list(curr, head, input);, curr und head aufrufen, werden sie selbst als Wert übergeben, und Änderungen an diesen Variablen (entsprechende Parameter) werden nicht an den Aufrufer zurückreflektiert.

Also, in dem Anrufer,

while(curr) 

zugreift unitialized Variable (meeory), die undefined behavior aufruft. Wenn Sie curr und head selbst ändern müssen, müssen Sie ihre Adresse übergeben und Änderungen an der Funktion vornehmen. So etwas wie

build_list(&curr, &head, input); 

und

void build_list(item **current, item **head, FILE *in) 

und

*current = malloc(sizeof(item)); 

kann die Arbeit für Sie erledigen.

+0

Ich habe getan, was Sie empfohlen haben, und es brachte eine ganze Reihe von Fehlern auf, wie 'Element Referenz Basistyp' Element * '(aka' Struct Gene * ') ist keine Struktur oder Union' und es warnt immer noch über die nicht initialisierte Variable. Was schief gelaufen ist? – matnnar

+0

@matnnar Entschuldigung, ich habe einen Fehler im Funktionsaufruf gemacht, bitte überprüfen Sie es jetzt. –

+0

Danke, aber es ist immer noch werfen 'Mitglied Referenz Basis Typ' Element ** '(aka' Struct Gene ** ') ist keine Struktur oder Union' als Fehler in den Zeilen 55 und 57. Können Sie mir erklären, wie ich könnte repariere das? – matnnar

Verwandte Themen