【问题标题】:How do I fix 'Segmentation fault (core dumped)' in this code?如何修复此代码中的“分段错误(核心转储)”?
【发布时间】:2020-02-04 01:36:22
【问题描述】:

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

这是我编写的代码。

#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)。我已经尝试在多台机器和编译器上运行代码,但仍然没有区别。

【问题讨论】:

  • 您应该包含stdlib.h 而不是malloc.h -- 后者不可移植。
  • 另外,不要使用void main()。请改用int main(void)
  • @JL2210 进行了更改。还是没有解决问题
  • 我不是说他们会。你的代码有比这更多的错误。这些只是风格变化。

标签: c linked-list queue


【解决方案1】:

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

正如您现在的代码所示,当您在函数内部更改 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);
  }
}  

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

      • enqueue() 在列表末尾添加一个新元素
      • dequeue() 从列表末尾删除一个元素
      • 全局frontNULL(空列表)或指向列表的第一个元素
      • 全局rearNULL(空列表)或指向列表的最后一个元素
      • 当列表为空时front == NULL rear == NULL
      • 如果列表有一个条目,那么front == rear
      • 如果列表不为空则rear-&gt;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
      ...
      

      【讨论】:

        猜你喜欢
        • 2017-04-05
        • 2021-06-23
        • 1970-01-01
        • 1970-01-01
        • 2022-10-13
        • 1970-01-01
        • 2018-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多