如何解决此代码中的“分段错误(核心已转储)”?

时间:2019-10-06 14:01:57

标签: c linked-list queue

我在链接列表,堆栈和队列中经常遇到这些错误。如果有人能一次又一次指出我犯的错误,那就太好了。

这是我编写的代码。

#include <stdio.h>
#include <malloc.h>

struct Node
{
    int data;
    struct Node* next;
}*front=NULL,*rear=NULL;
void enqueue(struct Node *front,struct Node *rear,int ele)
{
    struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
    struct Node* ptr=front;
    if (temp==NULL)
        printf("Overflow");
    else
    {
        if (front==NULL)
        {
    temp->data=ele;
    temp->next=NULL;
    front=temp;
    printf("%d",front->data);
    }
    else
    {
        printf("Srishti");
        while(ptr->next!=NULL)
        {
            ptr=ptr->next;
        }
        temp->next=front;
        ptr->next=temp;
        rear=temp;
    }
}
    }
void dequeue()
{
    struct Node *temp=front;
    if(front!=NULL && front->next!=NULL)
    {
        rear->next=front->next;
        front=front->next;
    }
}

void display()
{
    struct Node *temp=front;
    while(temp->next!=front)
    {
        printf("%d",temp->data);
        temp=temp->next;
    }
    printf("%d",rear->data);
}

void main()
{
    int n,i;
    for(i=0;i<3;i++)
    {
        printf("Enter Element");
        scanf("%d",&n);
        enqueue(front,rear,n);
    }

display();

}

我看到的输出始终为Segmentation Fault (core dumped)。我已经尝试在多台计算机和编译器上运行代码,但仍然没有区别。

3 个答案:

答案 0 :(得分:0)

通常请避免使用具有相同名称的全局变量和参数,这有点令人困惑,并可能导致您看到的问题。

现在,您的代码保持不变,当您在函数内更改front时,实际上并没有更改全局变量front,而是一个副本。

因此可以将前后地址传递给函数或完全删除参数。

void enqueue(struct Node **front,struct Node **rear,int ele)
{
  struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
  struct Node* ptr=*front;
...

if (front == NULL)
{
  temp->data = ele;
  temp->next = NULL;
  *front = temp;      // this will actually change front
  printf ("%d", front->data);
}

并命名为

int n, i;
for (i = 0; i < 3; i++)
{
  printf ("Enter Element");
  // scanf ("%d", &n); avoid using scanf like this, use instead fgets
  char line[32];
  if (fgets(line, sizeof(line), stdin) != NULL)
  { 
    int n = atoi(line); 
    enqueue (&front, &rear, n);
  }
}  

答案 1 :(得分:0)

以下代码可以正常运行而不会引发分段错误。我对代码做了一些小的更改。我想我在代码中的注释会解释您对代码所做的更改。

#include <stdio.h>
#include <malloc.h>

struct Node
{
    int data;
    struct Node* next;
}*front=NULL,*rear=NULL;

//remove the local arguments
void enqueue(int ele)
{
    struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
    struct Node* ptr=front;
    if (temp==NULL)
        printf("Overflow");
    else
    {
        if (front==NULL)
        {
            temp->data=ele;
            temp->next=NULL;
            front=temp;
            printf("%d",front->data);
        }
        else
        {
            printf("Srishti");
            // check the breaking condition
            while(ptr->next!=NULL && ptr->next != front)
            {
                ptr=ptr->next;
            }
            // putting the ele in the data space of Node
            temp->data = ele;
            temp->next=front;
            ptr->next=temp;
            rear=temp;
        }
    }
}

void dequeue()
{
    struct Node *temp=front;
    if(front!=NULL && front->next!=NULL)
    {
        rear->next=front->next;
        front=front->next;
    }
}

void display()
{
    struct Node *temp=front;
    while(temp->next!=front)
    {
        printf("%d",temp->data);
        temp=temp->next;
    }
    printf("%d",rear->data);
}

void main()
{
    int n,i;
    for(i=0;i<3;i++)
    {
        printf("Enter Element");
        scanf("%d",&n);
        enqueue(n);
    }

    display();

}

答案 2 :(得分:-1)

第一件事:始终启用编译器错误和警告。编译器是您的朋友,而不是您的敌人

从代码中不清楚您到底想要实现什么。因此,对于我的解决方案,我假设您需要以下条件:

  • enqueue()在列表末尾添加一个新元素
  • dequeue()从列表末尾删除一个元素
  • 全局frontNULL(空列表)或指向列表的第一个元素
  • 全局rearNULL(空列表)或指向列表的最后一个元素
  • 列表为空时,然后front == NULL rear == NULL
  • 如果列表中只有一个条目,则front == rear
  • 如果列表不为空,则rear->next == NULL

更新的代码:

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

struct Node {
  int data;
  struct Node* next;
} *front = NULL, *rear = NULL;

void enqueue(int ele)
{
  struct Node *temp = calloc(sizeof(struct Node), 1);

  if (temp == NULL) {
    printf("Overflow");
    exit(1);
  } else {

    if (front == NULL) {
      /* list is empty */
      front = temp;
    } else {
      /* add to end of list */
      rear->next = temp;
    }

    temp->data = ele;
    rear       = temp;
  }
}

void dequeue()
{
  /* special cases: empty or only one element */
  if (rear == front) {
    if (front != NULL)
      free(front);
    front = rear = NULL;
    return;
  }

  struct Node *temp = front;
  while (temp->next != rear)
    temp = temp->next;

  rear = temp;
  free(temp->next);
  temp->next = NULL;
}

void display()
{
  if (front == NULL)
    return;

  struct Node *temp = front;
  while (temp) {
    printf("%d\n", temp->data);
    temp = temp->next;
  }
  printf("\n");
}

int main(void)
{
  int n,i;

  for (i=0; i<3; i++) {
    printf("Enter Element ");
    scanf("%d",&n);
    enqueue(n);
  }

  /* show list & dequeue() functionality */
  for (i=0; i<3; i++) {
    display();
    dequeue();
  }
  display();

  /* show that dequeue() is safe on empty list */
  dequeue();

  return 0;
}

示例运行:

$ gcc -Wall -Werror -o dummy dummy.c
$ valgrind ./dummy
==9093== Memcheck, a memory error detector
...
Enter Element 1
Enter Element 2
Enter Element 3
1
2
3

1
2

1

==9093== 
==9093== HEAP SUMMARY:
==9093==     in use at exit: 0 bytes in 0 blocks
==9093==   total heap usage: 5 allocs, 5 frees, 2,096 bytes allocated
==9093== 
==9093== All heap blocks were freed -- no leaks are possible
...