C 自由链表

C 自由链表,c,linked-list,C,Linked List,我有一个链表,我想删除它的所有节点。问题是,如果我调用delete,它只打印出1,然后冻结。我读过其他类似的问题,但我不知道为什么会这样。我想我只是瞎了眼什么的 #include <stdio.h> #include <stdlib.h> typedef struct _node { int id; struct _node *next; } *node; typedef struct { node first; } *head; head newHea

我有一个链表,我想删除它的所有节点。问题是,如果我调用delete,它只打印出1,然后冻结。我读过其他类似的问题,但我不知道为什么会这样。我想我只是瞎了眼什么的

#include <stdio.h>
#include <stdlib.h>

typedef struct _node {
  int id;
  struct _node *next;
} *node;

typedef struct {
  node first;
} *head;

head newHead(node n) {
  head h = malloc(sizeof(node));
  h->first = n;
  return h;
}

node newNode(int id) {
  node n = malloc(sizeof(node));
  n->id = id;
  n->next = NULL;
  return n;
}

void delete(head h) {
  if(h->first == NULL) return;

  node current = h->first;
  while(current != NULL) {
    printf("%i", current->id);
    node tmp = current;
    current = current->next;
    free(tmp);
  }

  // free(h);
}

int main() {
  node n = newNode(1);
  head h = newHead(n);
  node n2 = newNode(2);
  node n3 = newNode(3);
  node n4 = newNode(4);
  n->next = n2;
  n2->next = n3;
  n3->next = n4;

  printf("%i", h->first->id);
  printf("%i", h->first->next->id);
  printf("%i", h->first->next->next->id);
  printf("%i", h->first->next->next->next->id);

  delete(h);

  return 0;
}
#包括
#包括
类型定义结构节点{
int-id;
结构_节点*下一步;
}*节点;
类型定义结构{
节点优先;
}*团长;
头部新头部(节点n){
头部h=malloc(节点尺寸);
h->first=n;
返回h;
}
节点newNode(int-id){
node n=malloc(sizeof(node));
n->id=id;
n->next=NULL;
返回n;
}
删除作废(标题h){
如果(h->first==NULL)返回;
节点电流=h->first;
while(当前!=NULL){
printf(“%i”,当前->id);
节点tmp=电流;
当前=当前->下一步;
免费(tmp);
}
//自由(h);
}
int main(){
节点n=新节点(1);
水头h=新水头(n);
节点n2=新节点(2);
节点n3=新节点(3);
节点n4=新节点(4);
n->next=n2;
n2->next=n3;
n3->next=n4;
printf(“%i”,h->first->id);
printf(“%i”,h->first->next->id);
printf(“%i”,h->first->next->next->id);
printf(“%i”,h->first->next->next->next->id);
删除(h);
返回0;
}

现在它可以工作了,我不得不改变这一点:

 n->next = n2;
 n2->next = n3;
 n3->next = n4;
为此:

 h->first->next = n2;
 h->first->next->next = n3;
 h->first->next->next->next = n4;

在函数
newNode
中,您分配的内存大小无效

node n = malloc(sizeof(node));
                       ^^^^ 
这不是为
struct\u节点
类型的对象分配内存,而是为指向
struct\u节点*
类型的对象的指针分配内存

你需要写作

node n = malloc(sizeof(struct _node));
`

您需要释放指针
h
指向的内存

函数
delete
可能如下所示

void delete( head *h ) 
{
    for ( node current = ( *h )->first; current != NULL; ) 
    {
        printf("%i", current->id);
        node tmp = current;
        current = current->next;
        free( tmp );
    }

    free( *h );

    *h = NULL;
}
打电话给我

delete( &h );
在这种情况下,退出函数后,指针
h
将等于
NULL

这是你的最新计划

#include <stdio.h>
#include <stdlib.h>

typedef struct _node {
  int id;
  struct _node *next;
} *node;

typedef struct {
  node first;
} *head;

head newHead(node n) {
  head h = malloc(sizeof(node));
  h->first = n;
  return h;
}

node newNode(int id) {
  node n = malloc(sizeof(struct _node));
  n->id = id;
  n->next = NULL;
  return n;
}

void delete( head *h ) 
{
    for ( node current = ( *h )->first; current != NULL; ) 
    {
        printf("%i", current->id);
        node tmp = current;
        current = current->next;
        free( tmp );
    }

    free( *h );

    *h = NULL;
}

int main() {
  node n = newNode(1);
  head h = newHead(n);
  node n2 = newNode(2);
  node n3 = newNode(3);
  node n4 = newNode(4);
  n->next = n2;
  n2->next = n3;
  n3->next = n4;

  printf("%i", h->first->id);
  printf("%i", h->first->next->id);
  printf("%i", h->first->next->next->id);
  printf("%i\n", h->first->next->next->next->id);

  delete( &h );

  return 0;
}
输出的第二行包含来自函数
delete
的测试消息

头h=malloc(节点大小)为结构分配了错误的大小;您可能打算
headh=malloc(sizeof(head))。使用
some_type*foo=malloc(sizeof(*foo))
有助于避免此类错误

除此之外,还有修改代码的空间。我不认为
抽象增加了任何价值;这是一个额外的间接层

if(h->first == NULL) return;
也是多余的,因为循环将处理这种情况

请不要键入定义指针。如果VAR旁边没有显式的
*
,则很难理解代码。事实上,我会更进一步,也不会定义结构。抑制有用信息会损害可读性

#include <stdio.h>
#include <stdlib.h>

struct node {
    int id;
    struct node *next;
};

struct node *make_node(int id) {
    struct node *n = malloc(sizeof(*n));
    n->id = id;
    n->next = NULL;
    return n;
}

void free_linked_list(struct node *head) {
    while (head) {
        struct node *tmp = head;
        head = head->next;
        free(tmp);
    }
}

int main() {
    struct node *head = make_node(1);
    head->next = make_node(2);
    head->next->next = make_node(3);

    printf("%d, ", head->id);
    printf("%d, ", head->next->id);
    printf("%d\n", head->next->next->id);

    free_linked_list(head);
    return 0;
}
#包括
#包括
结构节点{
int-id;
结构节点*下一步;
};
结构节点*make_节点(int-id){
结构节点*n=malloc(sizeof(*n));
n->id=id;
n->next=NULL;
返回n;
}
无效自由链接列表(结构节点*头){
while(head){
结构节点*tmp=head;
头部=头部->下一步;
免费(tmp);
}
}
int main(){
结构节点*head=make_节点(1);
head->next=make_节点(2);
head->next->next=制作节点(3);
printf(“%d”,head->id);
printf(“%d”,head->next->id);
printf(“%d\n”,head->next->next->id);
自由链接列表(标题);
返回0;
}

您是否尝试为列表定义并验证它们是否有效?在处理容易弄乱的代码(如列表等)时,此技术通常很有用。在main中,您设置了
head h=newHead(n)
,但在下面设置了
n->next=n2
不应该是
h->next=n2
?@burntchowmein它们是一样的,但应该是
h->first->next=n2好吧,那很有效。不可能!这是第一次我的“答案”是正确的。这个答案是错误的。这些错误会导致无效读取,调用可能会正常工作的未定义行为。
#include <stdio.h>
#include <stdlib.h>

struct node {
    int id;
    struct node *next;
};

struct node *make_node(int id) {
    struct node *n = malloc(sizeof(*n));
    n->id = id;
    n->next = NULL;
    return n;
}

void free_linked_list(struct node *head) {
    while (head) {
        struct node *tmp = head;
        head = head->next;
        free(tmp);
    }
}

int main() {
    struct node *head = make_node(1);
    head->next = make_node(2);
    head->next->next = make_node(3);

    printf("%d, ", head->id);
    printf("%d, ", head->next->id);
    printf("%d\n", head->next->next->id);

    free_linked_list(head);
    return 0;
}