以下链接列表代码有什么问题?获取细分错误

时间:2019-06-01 11:54:58

标签: c linked-list segmentation-fault singly-linked-list

我试图创建一个单链接列表并显示它。但是在这里,我遇到了细分错误。

当我使用MinGW编译器运行代码时,只要运行代码,exe文件就会继续崩溃。

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

typedef struct Node{
    int data;
    struct Node* next;
}node;
void print(node* head);

void main()
{
    node *head = NULL;
    head = malloc(sizeof(node));
    head->data= 4;
    head->next= malloc(sizeof(node));
    head->next->data= 5;
    head->next->next=malloc(sizeof(node));
    head->next->next->next->data = 6;
    head->next->next->next->next=NULL;
    print(head);
}
void print(node* head)
{
    node *current = head;
    while(current!= NULL)
    {
        printf("%d->",current->data);
        current=current->next;
    }

}

输出应为 4-> 5-> 6

2 个答案:

答案 0 :(得分:0)

  

我遇到了细分错误。

这是因为

head->next->next->next->data = 6;
head->next->next->next->next=NULL;

必须

head->next->next->data = 6;
head->next->next->next=NULL;

请注意,void main()必须为int main()


我鼓励您添加一个工作函数来创建一个新节点,这将大大简化您的代码,并且不会丢失指针,例如:

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

typedef struct Node{
  int data;
  struct Node* next;
} node;

void print(node* head);
node * make(int d, node * next);

int main()
{
    node * head = make(4, make(5, make(6, NULL)));

    print(head);
    return 0;
}

void print(node* head)
{
  node *current = head;
  while(current!= NULL)
  {
    printf("%d->",current->data);
    current=current->next;
  }
}

node * make(int d, node * n)
{
  node * r = malloc(sizeof(node));

  r->data = d;
  r->next = n;
  return r;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall m.c
pi@raspberrypi:/tmp $ ./a.out
4->5->6->pi@raspberrypi:/tmp $ 

可以改进您打印列表的方式,例如:

void print(node * current)
{
  if (current == NULL)
    puts("<empty list>");
  else {
    for (;;) {
      printf("%d", current->data);
      if ((current = current->next) == NULL)
        break;
      else
        fputs("->", stdout);
    }
    putchar('\n');
  }
}

现在执行产生了:

pi@raspberrypi:/tmp $ ./a.out
4->5->6
pi@raspberrypi:/tmp $

您分配资源,还需要释放它们,例如添加:

void del(node** head)
{
  while (*head) {
    node * d = *head;

    *head = (*head)->next;
    free(d);
  }
}

所以最后:

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

typedef struct Node{
  int data;
  struct Node* next;
} node;

void print(node* head);
node * make(int d, node * next);
void del(node** head);

int main()
{
    node * head = make(4, make(5, make(6, NULL)));

    print(head);
    del(&head);
    print(head);
    return 0;
}

void print(node * current)
{
  if (current == NULL)
    puts("<empty list>");
  else {
    for (;;) {
      printf("%d", current->data);
      if ((current = current->next) == NULL)
        break;
      else
        fputs("->", stdout);
    }
    putchar('\n');
  }
}

node * make(int d, node * n)
{
  node * r = malloc(sizeof(node));

  r->data = d;
  r->next = n;
  return r;
}

void del(node** head)
{
  while (*head) {
    node * d = *head;

    *head = (*head)->next;
    free(d);
  }
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall m.c
pi@raspberrypi:/tmp $ ./a.out
4->5->6
<empty list>
pi@raspberrypi:/tmp $ 

valgrind 下执行:

pi@raspberrypi:/tmp $ valgrind ./a.out
==8050== Memcheck, a memory error detector
==8050== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8050== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8050== Command: ./a.out
==8050== 
4->5->6
<empty list>
==8050== 
==8050== HEAP SUMMARY:
==8050==     in use at exit: 0 bytes in 0 blocks
==8050==   total heap usage: 4 allocs, 4 frees, 1,048 bytes allocated
==8050== 
==8050== All heap blocks were freed -- no leaks are possible
==8050== 
==8050== For counts of detected and suppressed errors, rerun with: -v
==8050== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi@raspberrypi:/tmp $ 

答案 1 :(得分:0)

错误的根源是程序文本的格式错误。:)

对于每个下一个节点,表达式左侧部分中的数据成员next的数量增加一个。:)

例如,您拥有的第一个(头)节点

    head->data = 4;
    head->next = malloc( sizeof( node ) );

对于第二个节点(左侧表达式中的另一个数据成员)

    head->next->data = 5;
    head->next->next = malloc( sizeof( node ) );

以此类推

    head->next->next->data = 6;
    head->next->next->next = NULL;

不要忘记在退出程序之前释放分配的内存。

请注意,根据C标准,不带参数的函数main应该声明为

int main( void )

这是一个演示程序

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

typedef struct Node
{
    int data;
    struct Node* next;
} node;

const node * print_list( const node *head )
{
    for ( const node *current = head; current != NULL; current = current->next )
    {
        printf( "%d -> ", current->data );
    }

    puts( "NULL" );

    return head;
}

void free_list( node **head )
{
    while ( *head )
    {
        node *tmp = *head;

        head = &( *head )->next;

        free( tmp );
    }
}

int main(void) 
{
    node *head = NULL;

    head = malloc(sizeof(node));
    head->data = 4;
    head->next = malloc( sizeof( node ) );

    head->next->data = 5;
    head->next->next = malloc( sizeof( node ) );

    head->next->next->data = 6;
    head->next->next->next = NULL;

    print_list( head );

    free_list( &head );

    return 0;
}

其输出为

4 -> 5 -> 6 -> NULL