这是我的代码(在链接列表上工作):
typedef struct node {
int data;
struct node_t* next;
} node_t;
typedef struct list{
node_t* head;
} list_t;
node_t* create_node(void){
node_t* tmp = malloc(sizeof(node_t));
if (tmp == NULL){
fprintf(stderr, "Error while allocating memory for node\n");
exit(EXIT_FAILURE);
}
return tmp;
}
void list_insert(list_t* list, node_t* node, int data){
if (node == NULL){
node_t* new = create_node();
new->next = list->head;
list->head = new;
new->data = data;
}
else{
node_t* current = list->head;
while(current != node){
current = current->next;
}
node_t* new = create_node();
new->next = current->next;
current->next = new;
new->data = data;
}
}
我在list_insert函数中确实得到了一些警告,但是我无法弄清它们的原因。如果作为参数传递的node
是NULL
,则此函数应在开头插入一个新节点,否则应在作为参数传递的node
之后插入一个新节点。
在此代码段中:
if (node == NULL){
node_t* new = create_node();
new->next = list->head;
list->head = new;
new->data = data;
}
分配new->next = list->head;
不正确。有任何猜测吗?
答案 0 :(得分:1)
在您对struct node
的定义中:
typedef struct node {
int data;
struct node_t* next;
} node_t;
您将next
定义为指向struct node_t
的指针,但是没有这种类型。您要struct node
:
typedef struct node {
int data;
struct node* next;
} node_t;
答案 1 :(得分:1)
您不需要typedef struct list{ ...}
,只需要一个node_t *
类型的变量,该变量始终包含列表的头,空时为NULL。
例如:
#include <stdlib.h>
#include <stdio.h>
typedef struct node {
int data;
struct node * next;
} node_t;
node_t* create_node(int data)
{
node_t* tmp = malloc(sizeof(node_t));
if (tmp == NULL){
fprintf(stderr, "Error while allocating memory for node\n");
exit(EXIT_FAILURE);
}
tmp->data = data;
tmp->next = NULL;
return tmp;
}
void list_append(node_t ** l, node_t* node){
if (*l == NULL) {
*l = node;
}
else {
while ((*l)->next != NULL)
l = &(*l)->next;
(*l)->next = node;
}
}
/* l, *l, where and node must not be NULL */
int list_insert(node_t ** l, node_t* where, node_t* node) {
if (*l != where) {
for (;;) {
if (*l == NULL)
return 0;
l = &(*l)->next;
if (*l = where)
break;
}
}
node->next = *l;
*l = node;
return 1;
}
void pr(node_t * l)
{
printf("list is :");
while (l != NULL) {
printf(" %d", l->data);
l = l->next;
}
putchar('\n');
}
void clear(node_t ** head)
{
node_t * l = *head;
while (l != NULL) {
node_t * n = l->next;
free(l);
l = n;
}
*head = NULL;
}
int main()
{
node_t * head = NULL;
node_t * n3 = create_node(3);
list_append(&head, create_node(1));
list_append(&head, n3);
pr(head);
list_insert(&head, n3, create_node(2));
pr(head);
list_insert(&head, head, create_node(0));
pr(head);
clear(&head);
pr(head);
return 0;
}
我当时更改了创建内容以便能够提供数据,这一点更加清晰了(就像C ++中的构造函数一样)
编译和执行:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra c.c
pi@raspberrypi:/tmp $ ./a.out
list is : 1 3
list is : 1 2 3
list is : 0 1 2 3
list is :
pi@raspberrypi:/tmp $ valgrind ./a.out
==27963== Memcheck, a memory error detector
==27963== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27963== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==27963== Command: ./a.out
==27963==
list is : 1 3
list is : 1 2 3
list is : 0 1 2 3
list is :
==27963==
==27963== HEAP SUMMARY:
==27963== in use at exit: 0 bytes in 0 blocks
==27963== total heap usage: 5 allocs, 5 frees, 1,056 bytes allocated
==27963==
==27963== All heap blocks were freed -- no leaks are possible
==27963==
==27963== For counts of detected and suppressed errors, rerun with: -v
==27963== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)