我正在尝试在C中实现链接列表,并且我想将头节点存储在单独的结构中。但是,每当我添加另一个节点时,似乎都会以某种方式重新分配头节点。
#include <stdio.h>
#include <stdlib.h>
struct BC_node {
struct BC_node *next;
void *data;
};
struct BC_list {
struct BC_node *head;
struct BC_node *tail;
};
void
BC_list_push(struct BC_list *list, void *data)
{
struct BC_node *node = calloc(1, sizeof(struct BC_node));
if (list->head != NULL)
printf("head: %d\n", *((int *) (list->head)->data));
node->next = NULL;
node->data = data;
if (list->head == NULL) {
printf("head is null.\n");
list->head = node;
}
if (list->tail != NULL) {
(list->tail)->next = node;
}
list->tail = node;
printf("head: %d\n", *((int *) (list->head)->data));
}
int
main(void)
{
int i;
struct BC_list *list = calloc(1, sizeof(struct BC_list));
list->head = NULL;
list->tail = NULL;
for (i = 0; i < 3; i++)
BC_list_push(list, &i);
return 0;
}
输出:
head is null.
head: 0
head: 1
head: 1
head: 2
head: 2
答案 0 :(得分:6)
您的data
成员只是指向i
中变量main
的指针,因此当您打印*data
时,您只需看到该轮中的计数器值循环。您的所有节点都具有相同的数据值!
答案 1 :(得分:2)
问题在于这一行:
BC_list_push(list, &i);
您正在传递i
的地址,这是您在循环中递增的整数(因此值会更改)。您需要为data
参数分配单独的内存。
for (i = 0; i < 3; i++)
{
int *d = malloc(sizeof(int));
*d = i;
BC_list_push(list, d);
}
但是当列表被销毁时不要忘记释放内存。
答案 2 :(得分:2)
情况更糟。 &amp; i是局部变量的地址,这意味着你从堆分配列表引用堆栈,volatile变量......这是完全错误的 - 如果你在一个不同于main的方法中执行它,那么局部变量你将会消失,你的指针将指向内存中的一些随机位置,可能指向其他变量或地址......非常糟糕。
答案 3 :(得分:1)
这是一个完整的示例,包含数据的结构和内存分配,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct BC_node{
void *data;
struct BC_node *next;
};
struct BC_list{
struct BC_node *head;
struct BC_node *tail;
};
struct BC_node *BC_new_node(void *data,size_t szdata)
{
struct BC_node *ptr=malloc(sizeof(struct BC_node));
if(ptr!=NULL){
ptr->data=malloc(szdata);
ptr->next=NULL;
if(ptr->data!=NULL)
memcpy(ptr->data,data,szdata);
else free(ptr),ptr=NULL;
}
return ptr;
}
int BC_list_push(struct BC_list *list,void *data,size_t szdata)
{
struct BC_node *ptr=BC_new_node(data,szdata);
if(list!=NULL && ptr!=NULL){
if(list->tail==NULL){
list->head=ptr;
list->tail=ptr;
} else {
list->tail->next=ptr;
list->tail=ptr;
}
return 0;
}
return 1;
}
void *BC_new_list(void)
{
struct BC_list *ptr=malloc(sizeof(struct BC_list));
if(ptr!=NULL)
ptr->head=ptr->tail=NULL;
return ptr;
}
void BC_free_list(struct BC_list *list)
{
struct BC_node *ptr;
while(list->head){
ptr=list->head->next;
free(list->head->data);
free(list->head);
list->head=ptr;
}
free(list);
}
void print_test(struct BC_list *list){
struct BC_node *ptr=list->head;
while(ptr){
printf("%s\n",(char*)ptr->data);
ptr=ptr->next;
}
}
int main(void)
{
char tab[3][40]={"hello","world","test"};
struct BC_list *list=BC_new_list();
if(list!=NULL){
BC_list_push(list,tab[0],strlen(tab[0])+1);
BC_list_push(list,tab[1],strlen(tab[1])+1);
BC_list_push(list,tab[2],strlen(tab[2])+1);
print_test(list);
BC_free_list(list);
}
return EXIT_SUCCESS;
}