删除c中链接列表中最后一项的问题

时间:2016-05-14 08:35:05

标签: c arrays struct linked-list malloc

我只是在学习c和链接列表我遇到了一些重大问题。

我有以下代码:

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

当我运行pop时,它应该与Javascript中的Array.prototype.pop类似。
它的表现非常奇怪,上一个next的名字是&#34; baz&#34;在我运行此代码而不是删除最后一个结构后,它只显示年龄为0.

似乎free并没有真正释放用malloc分配的指针。

3 个答案:

答案 0 :(得分:0)

例如

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

答案 1 :(得分:-1)

问题是,在void count(people array)中,current=current->next;将在while循环中分配。所以你需要确保在pop函数中将last-&gt; next分配给NULL。

我将你的pop功能修改为:

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

在pop功能中,您应该分配&#39; array&#39;的地址。到最后&#39;,然后指向&#39;数组&#39;到&#39; array-&gt; next&#39;

当程序从while循环中断时,您可以执行last->next=NULL;array=last;以确保最后一个结构正常。

答案 2 :(得分:-2)

如果您想使用自己的逻辑,那么:

//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);

这应该现在可以使用