C 通用链表库中的列表创建函数出现问题

C 通用链表库中的列表创建函数出现问题,c,C,我发现了一个我认为有用的通用链表库。但是llist_create(void*new_data)函数让我很困惑。指针new_列表分配两次。我可以看到,第一个malloc返回的地址将被第二个malloc覆盖。那么为什么要使用第一个malloc呢?(代码工作正常) 由于好奇,我试着通过评论第一个malloc来运行。然后gcc发出警告“从不兼容的指针类型初始化”。运行代码会导致分段错误 struct node { void *data; struct node *next; }; ty

我发现了一个我认为有用的通用链表库。但是llist_create(void*new_data)函数让我很困惑。指针new_列表分配两次。我可以看到,第一个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);

看起来你不熟悉c语言

是C语言和C++编程语言中的保留关键字。它用于为另一个数据类型创建别名。1因此,它通常用于简化声明由结构类型和联合类型组成的复杂数据结构的语法,但在为不同长度的整数数据类型提供特定的描述性类型名称时也很常见

现在看看这句话:

typedef struct node * llist;   
这意味着,
llist
struct node*
类型的别名

在这份声明中

llist *new_list = (llist *)malloc(sizeof (llist));
new\u list
的类型是
llist*
,它只不过是
struct节点**

因此,第一次分配给
new_list
的内存用于指向
struct节点的指针,第二次分配给指向
struct节点的指针


依我看,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>);
    .....
    .....
struct节点{
作废*数据;
结构节点*下一步;
};
typedef结构节点;
结构主义者{
节点*头;
};
typedef-struct-llist-llist;
LLIST*创建_列表(){
LLIST*LLIST=malloc(sizeof(LLIST));
if(llist==NULL)
退出(退出失败);
llist->head=NULL;
返回李斯特;
}
节点*创建节点(无效*数据){
NODE*NODE=malloc(sizeof(NODE));
if(node==NULL)
退出(退出失败);
节点->数据=数据;
节点->下一步=空;
返回节点;
}
//用于在列表开头插入节点的add函数
//参数:指向LLIST的指针
//要在节点中插入的数据
void add_list_head(LLIST*LLIST,void*data){
NODE*NODE=创建所有节点(数据);
如果(LIST->head!=NULL){
节点->下一步=llist->head;
}
llist->head=节点;
}
//驱动函数
int main(){
LLIST*LLIST=create_list();
.....
.....
添加列表标题(llist,);
添加列表标题(llist,);
.....
.....
正在执行2个操作,它正在创建一个新的列表头,并创建一个节点,其中包含头的数据引用

llist *new_list = (llist *)malloc(sizeof (llist));
首先,通过声明一个类型为llist*的新变量,并使用malloc为该指针创建内存,来创建一个列表头

//Second alloc
*new_list = (struct node *)malloc(sizeof (struct node));
创建一个新的
节点
,以保存提供的数据。 令人困惑的是,在
C
语法中,两个
*new\u list
的意思不同

llist *new_list; /* create a variable of pointer to llist */


函数的其余部分用
new_data

llist_create
填充
节点
,返回
struct节点**
(不知道为什么不仅仅是
struct节点*
)。第一个
malloc
struct节点*
分配空间(即为
*new_列表
),第二个-用于
结构节点
,它将
*新列表
指向指向指针的.first malloc
llist *new_list; /* create a variable of pointer to llist */
*new_list = val; /* write into what new_list is pointing at val */