2016-04-06 14 views
0

Ben insanlar hakkında bazı temel bilgileri içeren bir dizi ListNodes içeren bir LinkedList uygulayacağım. Ana dosya olan main.c ve diğeri main.h olan iki dosyam var. Kökeni bir işleve geçirerek yazdırmayı denediğimde, bir hata alıyorum. İşteSegmentasyon Bir başka işlev yerine aynı belleğe erişirken oluşan bir

main.c geçerli:

Benim main.h dosyasında
#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; 
} 

, ben işlevi "userLoop" kök parametresinin özelliklerini baskı sorunum yok, ama en kısa sürede ListNode * kökünü geçerken "print" veya "stuff" için değerleri yazdırmaya çalışırken bir seg hatası alıyorum. İşte

main.h geçerli:

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

} 

hem fonksiyonlarda kök hafızasında adresini baskı, aynı değer elde, bu yüzden ben değerleri erişemiyor neden emin değilim diğer işlev yerine bir işlevde kök.

Yardımlarınız için çok teşekkür ederim.

+0

Neden işlevinizi bir başlık dosyasında tanımlarsınız? – EOF

+0

neden daha iyi okunabilirlik için sorunuzu basitleştirmiyorsunuz. –

+0

, while-while sonra 'current-> next = NULL;' gerekir. – BLUEPIXY

cevap

0

64 bit sistemde olduğunuzu varsayalım, böylece işaretçiler 8 bayttır. & tamsayılar 4 bayttır. değil,% işaretçiler için% p kullan u

+0

Bu sadece farklı sonuçlar almadığımı doğrulamak içindi, bunun tüm adres olmadığını biliyorum, ancak aynı olduğundan emin olmak istedim. –

3

bellek modeli C. nasıl çalıştığını kod Kişisel kusurlu parça muhtemelen oldukça kavramak görünmüyor: Bu bir gösterici ile döner

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

yerel değişken toReturn, malloc bellek adresi değil. Verileri toReturn'dan malloc bellek alanına kopyalamanız gerekir. Bununla birlikte, daha da kötüsü, dizelerinizin her biri için yer açmazsınız, bu nedenle düğümlerinizin her biri aynı giriş arabelleğine işaret eder. Bu, her düğüm için malloc olduğundan çalışmalıdır, ancak eğer belleğini yöneten düğümleri silmeye başlayacaksanız, biraz garip olacaksınız. Ayrıca, tamponunuzda yeterli yer olduğundan emin değilsiniz.

C belleğinin nasıl çalıştığını yenilemek için bazı çevrimiçi kaynaklara (veya ideal olarak bir kitaba) bakmanızı öneririm.

Düzenleme: C çevrimiçi öğrenmedim, ancak hızlı bir bakış açısıyla hızlı bir bakışta iyi bir kaynak gibi görünen this açıldı.

book list'a bakmanızı öneriyorum. C Programlama Modern Bir Yaklaşım kullandım.

+0

Çok teşekkür ederim. Dizelerin her biri ayrı olarak hatalı veriler içeriyor, çünkü her yeni bir ListNode'umuz olduğunda "askForDetails" diyoruz, değil mi? –

+0

Evet, herşeyi serbest bırakan bir zamanın olacak. Ama evet, bence iyi olmalı. İlk başta bunu yanlış anladım, daha kötü olduğunu düşündüm. –

İlgili konular