2016-05-14 6 views
1

Ich lerne nur c und über verknüpfte Listen habe ich einige große Probleme.Probleme mit dem Entfernen des letzten Elements in einer verketteten Liste in c

Ich habe folgenden Code:

#include <stdio.h> 
#include <stdlib.h> 
struct people { 
    int age; 
    char *name; 
    struct people * next; 
}; 
typedef struct people people; 

void count(people array) { 
    people *current=malloc(sizeof(people)); 
    current = &array; 
    int count = 0; 
    while(current){ 
     count++; 
     printf("name %s\n",current->name); 
     printf("age %d\n",current->age); 
     current=current->next; 
    } 
    printf("%d\n", count); 
    free(current); 
} 
void push(people *array){ 
    people * new=malloc(sizeof(people)); 
    people *last=malloc(sizeof(people)); 
    new->age=300; 
    new->name="baz"; 
    new->next=NULL; 
    last=array; 
    while(last->next){ 
     last=last->next; 
    } 
    last->next=new; 
// free(new); 
} 
void pop(people *array){ 
    people * last=malloc(sizeof(people)); 
    last=array; 
    while(last->next){ 
     //get the last element in the list 
     last=last->next; 
    } 
// free the last element 
    free(last); 
} 
int main(int argc, char** argv) { 
    people person = { 
     .name = "foo", 
     .age = 25 
    }; 
    person.next = malloc(sizeof (people)); 
    person.next->age = 26; 
    person.next->name = "bar"; 
    person.next->next = NULL; 
    //push into the list 
    push(&person); 
    //count after pushing 
    count(person); 
    //remove last 
    pop(&person); 
    //at this count i get just the age 0 but the name was not removed and still counts 3 
    count(person); 
    return 0; 
} 

Wenn ich Pop laufen es soll zu Array.prototype.pop von Javascript ähnlich arbeiten.
Es verhält sich wirklich seltsam die letzten next den Namen „baz“ und Alter hat 300. Nachdem ich diesen Code ausführen, anstatt diese letzte Struktur zu entfernen, es zeigt nur das Alter als 0

frei scheint, ist nicht wirklich um die Zeiger zu befreien zugewiesen mit malloc.

+2

Das Vorletzte verweist immer noch auf ungültigen Speicher. free() gibt nur den angegebenen Speicherabschnitt zurück an den Speicherzuordner, setzt Ihre Zeiger nicht auf gültigen Speicher – GeorgeAl

+1

Zusätzlich zu @GeorgeAl kommentieren Sie Tonnen von Speicher. Aktuelle und letzte erhalten ihren eigenen Speicher, dann löschen Sie sie einfach, indem Sie den/die Zeiger anderen Adressen zuweisen. – Andreas

+0

@GeorgeAl wie kann ich ein zugewiesenes Speicherstück freigeben, wenn das freie nicht funktioniert? – nikoss

Antwort

0

Beispiel

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

typedef struct people { 
    int age; 
    char *name; 
    struct people * next; 
} people; 


people *new_people(const char *name, int age){ 
    people *node = malloc(sizeof(people)); 
    char *copy_name = malloc(strlen(name)+1); 
    strcpy(copy_name, name); 

    node->age = age; 
    node->name = copy_name; 
    node->next = NULL; 
    return node; 
} 

void free_people(people *p){ 
    free(p->name); 
    free(p); 
} 

void count(people *array) { 
    people *current = array; 
    int count = 0; 

    while(current){ 
     count++; 
     printf("name %s\n", current->name); 
     printf("age %d\n", current->age); 
     current = current->next; 
    } 
    printf("%d\n", count); 
} 

void push(people **array, people *addNode){ 
    if(*array == NULL){ 
     *array = addNode; 
     return ; 
    } 

    people *last = *array; 
    while(last->next){ 
     last = last->next; 
    } 
    last->next = addNode; 
    //return length; 
} 

people *pop(people **array){ 
    if(*array == NULL) 
     return NULL; 

    people *last = *array; 
    people *prev = NULL; 
    while(last->next){ 
     prev = last; 
     last=last->next; 
    } 
    if(prev != NULL) 
     prev->next = NULL; 
    else 
     *array = NULL; 
    return last; 
} 

int main(void) { 
    people *array = NULL; 
    push(&array, new_people("foo", 25)); 
    push(&array, new_people("bar", 26)); 
    push(&array, new_people("baz", 300)); 

    count(array); 
    people *baz = pop(&array); 
    free_people(baz); 
    count(array); 

    people *bar = pop(&array); 
    free_people(bar); 
    people *foo = pop(&array); 
    free_people(foo);//free_people(pop(&array)) 

    return 0; 
} 
-2

Wenn Sie eine eigene Logik verwenden wollen, dann:

//use double pointer here, and send the head of the list 
void pop(people **array) { 
    people *last = *array; //asign like this 
    while(last) { // not last->next 
     last = last->next; 
    } 
    last = NULL; 
    free(last); 
} 

//call like this 
pop(&list); 

diese

+0

Das doesn ' schau richtig. ITYM 'while (letzte = * array) {array = & last-> next; } 'und' last = NULL; frei (last); 'ist auch falsch. – wildplasser

+1

wo kam das von * array = & last-> next; *? du hast dir meinen Code vorher gar nicht angesehen, bevor du abstimmst .... –

+1

[Ich glaube, du hast deinen eigenen Code nicht gelesen, bevor du ihn eingereicht hast] Nach deiner while-Schleife ist der letzte NULL. es muss sein. Dann setzen Sie es auf NULL. Dann befreit du es. Und: Ja, ich habe einen Fehler gemacht: es hätte 'while sein müssen ((last = * array) && last-> next) {array = & last-> next; } – wildplasser

-1

Das Problem arbeiten jetzt sollte, ist, dass in der void count(people array), current=current->next; zugeordnet werden würde in der While-Schleife. Sie müssen also sicherstellen, dass last-> next in der Pop-Funktion NULL zugewiesen wird.

I geändert Ihre Pop-Funktion:

void pop(people *array){ 

    people * last=malloc(sizeof(people)); 

    while(array->next){ 
     last=array; 
     array=array->next; 
     if(array->next){ 
      //get the last element in the list 
      last=last->next; 
     }else{ 
      break; 
     }                        
    } 
    last->next=NULL; 
    array=last; 
} 

In der Pop-Funktion sollten Sie die Adresse des 'Array' auf 'letzte', zuweisen und zeigt dann die 'Array' auf ‚Array-> weiter ".

Da das Programm aus der while-Schleife bricht, können Sie last->next=NULL; und array=last; tun, um sicherzustellen, dass die letzte Struktur in Ordnung ist.