2016-04-06 7 views
0

Ich implementiere eine LinkedList mit einer Reihe von ListNodes, die Strukturen sind, die einige grundlegende Informationen über Personen enthalten. Ich habe zwei Dateien, eine, die main.c ist, und eine andere, die main.h. Immer wenn ich versuche, die Liste zu drucken, indem ich den Stamm an eine Funktion übergebe, erhalte ich einen Fehler.Segmentierung Fehler beim Zugriff auf den gleichen Speicher in einer Funktion anstelle einer anderen

Hier ist main.c:

#include "main.h" 

/* Edward Nusinovich 

    This C file is going to have a LinkedList containing information about people. 
    The user can interact with it and manipulate the list. 

*/ 

int main(int argc, char **argv){ 

    if(!checkIfValidArguments(argc).value){return -1;} 

    ListNode *root = askForDetails(1,argv); 
    ListNode *current = root; 
    current->next = NULL; 

    ListNode *temp; 

    int index = 2; 

    while(index<argc){ 
     temp = askForDetails(index,argv); 
     current->next = temp; 
     current = current->next; 
     index++; 
    } 

    userLoop(root); 

    return 0; 
} 

In meiner main.h Datei, ich habe kein Problem beim Drucken Attribute des Wurzel Parameter in der Funktion "userLoop", aber sobald ich ListNode * Wurzel um "drucken" oder "stopfen" bekomme ich einen seg Fehler, wenn ich versuche, seine Werte zu drucken.

Hier ist main.h:

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

#define true 1 
#define false 0 

typedef struct bool{ 
    int value:1; 
} boolean; 

//this is going to store info about a person 
typedef struct people{ 

    char *name; 
    char *hairColor; 
    char *eyeColor; 
    char *age; 
    struct people *next;  

} ListNode; 

//using a 1 bit bitfield we have constructed, stores whether or not the user has entered a proper number of inputs 
boolean checkIfValidArguments(int numArgs){ 

    boolean validArguments; 

    if(numArgs>1){validArguments.value=true;} 
    else{validArguments.value=false; printf("We need some names of people.\n");} 

    return validArguments; 
} 

//this will construct a new Person and return him to 
ListNode *askForDetails(int personIndex, char **argv){ 

    ListNode toReturn; 

    char *name = argv[personIndex]; 
    printf("Please enter the hair color, eye color, and age of %s.\n",name); 

    char *inBuf=malloc(100); 
    char nextchar=getchar(); 
    int index = 0; 

    if(nextchar!='\n'){inBuf[index]=nextchar; index++;} 

    while((nextchar=getchar())!='\n'){ 
     inBuf[index] = nextchar; 
     index ++; 
    } 

    toReturn.name = name; 
    toReturn.hairColor = strtok(inBuf," "); 
    toReturn.eyeColor = strtok(NULL," "); 
    toReturn.age = strtok(NULL,"\n"); 

    ListNode *newNode = malloc(sizeof(ListNode)); 
    newNode = &toReturn;  
    return newNode; 
} 

char *getInput(char *message){ 

    printf("%s",message); 
    char *inBuf = malloc(40); 
    char nextchar=getchar(); 
    int index = 0; 
    if(nextchar!='\n'){inBuf[index]=nextchar; index++;} 

    while((nextchar=getchar())!='\n'){ 
     inBuf[index] = nextchar; 
     index ++; 
    } 

    return inBuf; 

} 

void addToEnd(ListNode *root){ 

    ListNode *current = root; 

    char *inBuf = getInput("\nEnter the name of a person who you want to add: \n"); 

    ListNode *toAdd = malloc(sizeof(ListNode)); 
    toAdd = askForDetails(0,&inBuf); 
    toAdd->name = inBuf; 
    toAdd->next = NULL; 

    while((current->next) != NULL){ 
     current = current->next; 
    } 

    current->next = toAdd; 
} 


void print(ListNode *root){ 

    printf("The name is %s.\n",root->name); 
/* 
    ListNode *current = root; 

    do{ 
     printf("\n%s's hair is %s, their eyes are %s and they are %s years old.\n",current->name,current->hairColor,current->eyeColor,current->age); 
     current = current->next; 
    }while(current!=NULL); 
*/ 

} 

void remEnd(ListNode *root){ 

    ListNode *current = root; 

    if(current == NULL){ return; } 





} 

void addAfter(ListNode *root){ 

    ListNode *current = root; 

    char *name = getInput("\nWho do you want to add after?\n"); 
    int comparison = 0; 

    while(current!=NULL&&(comparison = strcmp(name,current->name))!=0){ 
     current = current -> next; 
    } 

    if(current==NULL){printf("\nIndividual not found.\n"); return;} 

    else{ 
     char *newPerson = getInput("What's the name of the person you wish to add? "); 

     ListNode *toAdd = askForDetails(0,&newPerson); 
     ListNode *next = current->next; 
     current -> next = toAdd; 
     toAdd->next = next; 
     return; 
    } 

} 

void stuff(ListNode *root){ 
    printf("name is %s.\n",root->name); 
    printf("Root lives at %u.\n",root); 
} 

void userLoop(ListNode *root){ 

    char input = ' '; 

    printf("Root lives at %u.\n",root); 

    while(true){ 
     printf("name is %s.\n",root->name);  

     if(input!='\n'){ 
      printf("\nWhat would you like to do with your list:\n"); 
      printf("A) Add an element at the end of the list\n"); 
      printf("B) Remove an element from the end of the list\n"); 
      printf("C) Add an element after an element on your list\n"); 
      printf("D) Print your list\n"); 
      printf("E) Quit this program\n\n"); 
     } 

     input = getchar(); 

     switch(input){ 
      case 'A': addToEnd(root); break;    
      case 'B': remEnd(root); break; 
      case 'C': addAfter(root); break; 
      case 'D': stuff(root); break; 
      case 'E': return; 
     } 
    } 

} 

Wenn die im Speicher in beiden Funktionen der Wurzel Adresse drucken, ich den gleichen Wert, so dass ich bin mir nicht sicher, warum ich nicht in der Lage bin, die Werte für den Zugriff auf in Wurzel in einer Funktion anstelle der anderen.

Vielen Dank für jede Hilfe.

+0

Warum würden Sie Ihre Funktion in einer Header-Datei definieren? – EOF

+0

Warum vereinfachen Sie Ihre Frage nicht für bessere Lesbarkeit. –

+0

brauchen Sie 'current-> next = NULL;' nach while-Schleife. – BLUEPIXY

Antwort

0

Ich gehe davon aus, Sie sind auf einem 64-Bit-System, so dass Zeiger 8 Bytes sind & Integer sind 4 Bytes. Verwenden Sie% p für Zeiger, nicht% u

+0

Das war nur um zu bestätigen, dass ich keine anderen Ergebnisse bekommen habe, ich weiß, dass es nicht die ganze Adresse ist, aber ich wollte sicherstellen, dass es dasselbe ist. –

3

Sie scheinen nicht ganz zu begreifen, wie das Speichermodell in C. Stück Code Ihr säumige funktioniert, ist wahrscheinlich:

ListNode *newNode = malloc(sizeof(ListNode)); 
newNode = &toReturn;  
return newNode; 

Dieser einen Zeiger auf die zurück lokale Variable toReturn, nicht die malloc'd Speicheradresse. Sie müssen die Daten von toReturn in Ihren malloc'd Speicherplatz kopieren. Schlimmer noch, Sie haben keinen Platz für jeden Ihrer Strings, also zeigt jeder Ihrer Knoten auf den gleichen Eingabepuffer. Dies sollte funktionieren, da Sie malloc mit jedem Knoten, aber wenn Sie beginnen werden, Knoten zu löschen, die Ihren Speicher verwalten, wird ein wenig peinlich sein. Sie stellen auch nicht sicher, dass in Ihrem Puffer genügend Platz ist.

Ich schlage vor, einige Online-Ressourcen (oder idealerweise ein Buch) zu betrachten, um zu aktualisieren, wie C-Speicher funktioniert.

Edit: Ich habe C nicht online gelernt, aber eine schnelle Google-Suche ergab this, die auf einen schnellen Blick scheint eine anständige Ressource zu sein.

Ich würde empfehlen, in book list zu suchen. Ich habe C Programmierung eine moderne Methode verwendet.

+0

Vielen Dank. Jede der Zeichenfolgen hat jedoch getrennt malloc'd Daten, weil wir jedes Mal, wenn wir einen neuen ListNode haben, "askForDetails" aufrufen, oder? –

+0

Ja, außer dass du eine Zeit davon haben wirst, alles zu befreien. Aber ja, sollte in Ordnung sein, denke ich. Ich habe es zuerst falsch gelesen, dachte, es sei schlimmer als es ist. –

Verwandte Themen