Как исправить ошибку сегментации (ядро сброшено) в этом коде? - PullRequest
0 голосов
/ 06 октября 2019

Я очень часто получаю эти ошибки в связанных списках, стеках и очередях. Было бы замечательно, если бы кто-нибудь снова и снова указывал на ошибку, которую я совершаю.

Вот код, который я написал.

#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 голосов
/ 06 октября 2019

как правило, избегайте использования глобальных переменных и аргументов с одинаковыми именами, это немного сбивает с толку и, возможно, вызывает проблему, которую вы видите.

в том виде, в каком ваш код теперь стоит, когда вы изменяете 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);
  }
}  
0 голосов
/ 06 октября 2019

Следующий код работает без выброса ошибки сегментации. Я сделал несколько небольших изменений в коде. Я думаю, мои комментарии внутри кода объяснят изменения, внесенные в ваш код.

#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();

}
0 голосов
/ 06 октября 2019

Перво-наперво: всегда включать ошибки и предупреждения компилятора. Компилятор - ваш друг , а не враг !

Из кода не ясно, чего именно вы хотите достичь. Поэтому для моего решения я предполагаю, что вы хотите следующее:

  • enqueue() добавляет новый элемент в конец списка
  • dequeue() удаляет элемент изконец списка
  • global front либо NULL (пустой список), либо указатель на первый элемент списка
  • global rear либо NULL (пустой список) или указывает на последний элемент списка
  • , когда список пуст, затем 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
...
...