2016-12-07 4 views
2

Ich habe eine verknüpfte Liste Programm geschrieben, die Datenelement als void * speichert. während ich versuche, den annd print unter Verwendung von scanf/printf-Funktionen zu speichern, erhalte ich einen Segmentierungsfehler.Speichern und Drucken Zeichenfolge in ungültigen Zeiger

Knotendefinition ->

typedef struct node { 
     struct node *next; 
     void *data; 
     }node; 

Hauptfunktion ->

   head=(node *)malloc(sizeof(node)); 
       if (head==NULL){ 
         printf("error in allocation of memory\n"); 
         exit(EXIT_FAILURE); 
       } 
       tail=(node*)create(head); 

Funktion erstellen ->

void *create(node *current) 
{ 
     int user_choice; 
     while(current){ 
       printf("\nEnter the data:"); 
       scanf("%s",current->data); 
       printf("stored at %p\n",(void*)current->data); 
       printf("%s",(char*)current->data); 
       printf("\nType '1' to continue, '0' to exit:\n"); 
       scanf("%d",&user_choice); 

       if(user_choice == 1){ 
         current->next=(node*)malloc(sizeof(node)); 
         current=current->next; 
       } 
       else{ 
         current->next=NULL; 
       } 
     } 
     return current; 
} 

kann jemand sagen, was ist das richtige Argument für scanf & prinf sollte ..?


Arbeits Code nach Punkten gegeben in Antworten ...

void *create(node *current) 
{ 
     node *temp; 
     int user_choice; 
     while(current){ 
       printf("\nEnter the data:"); 
       current->data=(char*)malloc(10*sizeof(char)); 
       scanf("%s",current->data); 
       printf("stored at %p\n",(void*)current->data); 
       printf("%s",(char*)current->data); 
       printf("\nType '1' to continue, '0' to exit:\n"); 
       scanf("%d",&user_choice); 

       if(user_choice == 1){ 
         current->next=(node*)malloc(sizeof(node)); 
       } 
       else{ 
         current->next=NULL; 
         temp=current; 
       } 
       current=current->next; 
     } 
     return temp; 
} 
+0

[Bitte sehen Sie diese Diskussion darüber, warum nicht den Rückgabewert von 'malloc()' und Familie in 'C' zu werfen.] (Http://stackoverflow.com/q/605845/2173917). –

+1

Wenn der Benutzer 0 drückt, gibt die Funktion NULL zurück. Es gibt viele Fehler. Bitte lesen Sie ein Buch, überdenken Sie Ihren Code und kommen Sie zurück, wenn Sie Probleme haben. –

+1

Wenn 'head' null ist und Sie die Fehlermeldung ausgeben (die zu stderr, nicht zu stdout gehen soll), sollten Sie etwas anderes tun, als mit der nächsten Zeile fortzufahren, die' head' be non-null erfordert. Ihr Programm hat ein undefiniertes Verhalten. –

Antwort

3

in Ihrem Code

scanf("%s",current->data); 

ist Versuch zu machen, die Verwendung eines unitialized Zeiger enthält, es ruft undefined behavior auf.

Sie müssen entweder von unten Ansatz folgen,

  • den Zeiger Punkt gültigen Teil des Speichers machen (malloc() und Familie für die dynamische Zuordnung verwendet, zum Beispiel)
  • einen Array verwenden.
+0

Ich habe Speicher zugewiesen, um in Hauptfunktion, die als aktuelle in create function übergeben wird ... –

+4

@HimanshuSourav genau, haben Sie für 'zugeordnet head', nicht für 'head-> data'. denke aus dieser Perspektive. –

1

Sie sollten erste Datenelement der Struktur initialisiert werden, da

current->data = malloc("passes size here"); 

Für Daten setzen Sie zunächst diese Daten typisieren, weil Leere nicht Speichertyp ist. void pointer kann verwendet werden, um auf einen beliebigen Datentyp zu zeigen.

Wie

*(char *)(current->data) = 1; 
-1

Bitte versuchen Sie es mit diesem

void *create(node *current) 
{ 
     int user_choice; 
     while(true){ 
       if(current == NULL) { 
        current = (node *)malloc(sizeof(node)); 
        current->data = NULL; 
        current->next = NULL; 
       } 
       printf("\nEnter the data:"); 
       scanf("%s",current->data); 
       printf("stored at %p\n", (void *)current->data); 
       printf("%s",current->data); 
       //printf("%s",(char*)current->data); 
       printf("\nType '1' to continue, '0' to exit:\n"); 
       scanf("%d",&user_choice); 

       if(user_choice == 1){ 
         current->next=(node*)malloc(sizeof(node)); 
         current=current->next; 
       } 
       else{ 
         current->next=NULL; 
         tail = current; 
         current=current->next; 
         break; 
       } 
     } 
     return current; 
} 

Hinweis: Das Element initialisiert werden muss (dh, es hat mit einigen Speicher alloted werden), bevor wir Gebrauch zu machen versuchen, davon.

+0

Sie zeigen nicht, dass Sie zu irgendeinem Zeitpunkt Speicher für 'current-> data' zugewiesen haben. Sie initialisieren auch nicht immer alle Elemente eines neu zugewiesenen Knotens. In C müssen Sie immer darüber nachdenken, "wohin meine Zeiger zeigen". –

+0

'current = (node ​​*) malloc (sizeof (node))' 'Alloking Speicher eines Knotens reserviert Speicher für seine Elemente wie' current-> data' und 'current-> next' – lsof

+2

Aber' current-> data' wird Halten Sie einen 'void *' -Zeiger, der vor der Verwendung zugewiesen werden muss. – RoadRunner

1

Wie andere gesagt haben:

scanf("%s",current->data); 

Ist in C undefined current->data irgendwo werden muss zeigen, bevor Sie etwas darin speichern.

Sie sollten stattdessen:

  1. Accept Eingabe von scanf.
  2. In temporärem Puffer speichern.
  3. Legen Sie in verketteten Liste
  4. Druck
  5. am Ende
  6. free() verknüpfte Liste am Ende ganzen verknüpften Liste aus.

ich auch Ihren Code in verschiedenen Funktionen das Gefühl, dass Ihre aktuelle void *create Funktion zu viel tut, und es wäre einfacher zu zerlegen, nur um es einfacher zu machen, alle Zeigeroperationen zu handhaben, usw.

Einfügen

Um diese Punkte zu demonstrieren, habe ich vor einiger Zeit etwas Code geschrieben, der diese Dinge erledigt und modifiziert wurde, um Ihnen bei Ihrem Code zu helfen. Es ist nicht der beste Code, aber er verwendet diese Punkte, die Ihnen bei Ihrem Code helfen.

Hier ist sie:

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

#define MAXSTRLEN 100 

typedef struct node { 
    void *data; 
    struct node *next; 
} node_t; 

typedef struct { 
    node_t *head; 
    node_t *foot; 
} list_t; 

list_t *create_list(void); 
node_t *generate_node(void); 
list_t *insert_node(list_t *list, char *data); 
void print_list(list_t *list); 
void free_list(list_t *list); 

int 
main(int argc, char *argv[]) { 
    list_t *list; 
    char data[MAXSTRLEN]; 
    int user_choice; 

    list = create_list(); 

    while (1) { 
     printf("Enter the data: "); 
     scanf("%s", data); 

     printf("\nType '1' to continue, '0' to exit:\n"); 
     if (scanf("%d",&user_choice) != 1) { 
      printf("Invalid input\n"); 
      exit(EXIT_FAILURE); 
     } 

     if (user_choice == 1) { 
      list = insert_node(list, data); 
     } else { 
      list = insert_node(list, data); 
      break; 
     } 
    } 

    print_list(list); 

    free_list(list); 
    list = NULL; 

    return 0; 
} 

/* inserting at foot, you can insert at the head if you wish. */ 
list_t 
*insert_node(list_t *list, char *data) { 
    node_t *newnode = generate_node(); 

    newnode->data = malloc(strlen(data)+1); 
    strcpy(newnode->data, data); 

    newnode->next = NULL; 
    if (list->foot == NULL) { 
     list->head = newnode; 
     list->foot = newnode; 
    } else { 
     list->foot->next = newnode; 
     list->foot = newnode; 
    } 
    return list; 

} 

node_t 
*generate_node(void) { 
    node_t *new = malloc(sizeof(*new)); 
    new->data = NULL; 
    return new; 
} 

void 
print_list(list_t *list) { 
    node_t *curr = list->head; 

    printf("\nlinked list data:\n"); 
    while(curr != NULL) { 
     printf("%s\n", (char*)curr->data); 
     curr = curr->next; 
    } 
} 

list_t 
*create_list(void) { 
    list_t *list = malloc(sizeof(*list)); 

    if (list == NULL) { 
     fprintf(stderr, "%s\n", "Error allocating memory"); 
     exit(EXIT_FAILURE); 
    } 

    list->head = NULL; 
    list->foot = NULL; 
    return list; 
} 

void 
free_list(list_t *list) { 
    node_t *curr, *prev; 
    curr = list->head; 
    while (curr) { 
     prev = curr; 
     curr = curr->next; 
     free(prev); 
    } 
    free(list); 
} 

UPDATE:

Beachten Sie auch, wie ich Speicher für newnode->data zugewiesen?

So:

newnode->data = malloc(strlen(data)+1); //using buffer from scanf 

Dies nun bedeutet, dass ich Daten in diesem Zeiger speichern, Ihre current->data müssen etwas Ähnliches tun.

1

Arbeits Code ->

void *create(node *current) 
{ 
     node *temp; 
     int user_choice; 
     while(current){ 
       printf("\nEnter the data:"); 
       current->data=(char*)malloc(10*sizeof(char)); 
       scanf("%s",current->data); 
       printf("stored at %p\n",(void*)current->data); 
       printf("%s",(char*)current->data); 
       printf("\nType '1' to continue, '0' to exit:\n"); 
       scanf("%d",&user_choice); 

       if(user_choice == 1){ 
         current->next=(node*)malloc(sizeof(node)); 
       } 
       else{ 
         current->next=NULL; 
         temp=current; 
       } 
       current=current->next; 
     } 
     return temp; 
} 
+0

Nice @Himanshu Sourav, hat mein Code überhaupt geholfen? – RoadRunner

+0

@RoadRunner es tat tatsächlich :) –

Verwandte Themen