我发现了一个通用的链表库,我认为这很有用。但是llist_create(void * new_data)函数使我感到困惑。指针new_list被分配两次。我看到的是,第一个malloc返回的地址将被第二个malloc覆盖。那么为什么要使用第一个malloc? (代码效果很好)
由于我好奇,我尝试通过注释第一个malloc来运行。然后,gcc发出警告“从不兼容的指针类型初始化”。运行代码会导致分段错误。
struct node {
void *data;
struct node *next;
};
typedef struct node * llist;
llist *llist_create(void *new_data)
{
struct node *new_node;
//First alloc
llist *new_list = (llist *)malloc(sizeof (llist));
//Second alloc
*new_list = (struct node *)malloc(sizeof (struct node));
new_node = *new_list;
new_node->data = new_data;
new_node->next = NULL;
return new_list;
}
//Code which creates linked list in driver program
llist *my_list = llist_create(NULL);
答案 0 :(得分:0)
好像您不熟悉c中的typedef。
typedef是C和C ++编程语言中的保留关键字。它用于为另一种数据类型创建别名。1因此,它通常用于简化声明由struct和Union类型组成的复杂数据结构的语法,但在为整数提供特定的描述性类型名称时一样常见。长度不同的数据类型。
现在看一下这句话:
typedef struct node * llist;
这意味着llist
是struct node *
类型的别名。
在此声明中
llist *new_list = (llist *)malloc(sizeof (llist));
new_list
的类型为llist *
,除了struct node **
之外什么都没有。
因此,对new_list
的第一个内存分配是指向指向struct node
的指针的指针,而第二个分配是对指向struct node
的指针。
IMO,OP发布的代码令人困惑,原因有两个:
-typedef指向结构的指针
-创建列表和在列表中添加节点这两个操作组合在一个函数中。
更具可读性的代码如下:
struct node {
void *data;
struct node *next;
};
typedef struct node NODE;
struct llist {
NODE *head;
};
typedef struct llist LLIST;
LLIST *create_list() {
LLIST *llist = malloc(sizeof(LLIST));
if (llist == NULL)
exit(EXIT_FAILURE);
llist->head = NULL;
return llist;
}
NODE *create_ll_node(void *data) {
NODE *node = malloc(sizeof(NODE));
if (node == NULL)
exit(EXIT_FAILURE);
node->data = data;
node->next = NULL;
return node;
}
// The add function for inserting node at the start of list
// Parameter: pointer to LLIST
// data to be insert in node
void add_list_head(LLIST *llist, void *data) {
NODE *node = create_ll_node(data);
if (llist->head != NULL) {
node->next = llist->head;
}
llist->head = node;
}
//driver function
int main() {
LLIST *llist = create_list();
.....
.....
add_list_head(llist, <data>);
add_list_head(llist, <data>);
.....
.....
答案 1 :(得分:0)
llist *llist_create(void *new_data)
正在执行2个操作,它是创建一个新的列表头,并创建一个节点,并为该头提供数据引用。
llist *new_list = (llist *)malloc(sizeof (llist));
首先通过声明类型为llist *的新变量并使用malloc为该指针创建内存来创建列表头。
//Second alloc
*new_list = (struct node *)malloc(sizeof (struct node));
创建一个新的node
来保存提供的数据。
两种C
在*new_list
语法中令人困惑,意思不同。
llist *new_list; /* create a variable of pointer to llist */
和 new_list = val; / 写入new_list指向val * /
该函数的其余部分用node
填充new_data