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



我只是在学习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 %sn",current->name);
        printf("age %dn",current->age);
        current=current->next;
    }
    printf("%dn", 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的名字是"baz",年龄是300岁,这真的很奇怪。在我运行这段代码后,它只是将年龄显示为0,而不是删除最后一个结构。

看起来free并没有真正释放用malloc分配的指针。

示例

#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 %sn", current->name);
        printf("age %dn",  current->age);
        current = current->next;
    }
    printf("%dn", 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;
}

问题是,在void count(people array)中,current=current->next;将在while循环中分配。因此,您需要确保在pop函数中将last->next赋值为NULL。

我把你的弹出功能修改为:

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函数中,您应该将"array"的地址分配给"last",然后将"array"指向"array->next"。

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

相关内容

  • 没有找到相关文章

最新更新