我只是在学习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;
以确保最后一个结构是正确的。