【问题标题】:Why am i gettting segmentation fault (core dumped) in my C queue?为什么我的 C 队列中出现分段错误(核心转储)?
【发布时间】:2017-02-08 13:01:31
【问题描述】:

所以我试图在 C 中实现队列数据结构,但我不断收到此错误:分段错误(核心转储)。我认为它来自我的入队方法。谁能帮我解决这个问题...

这是我的 queue.c 文件

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

void createQueue(LinkedList* list)
{
  list = (LinkedList*)calloc(1, sizeof(LinkedList));
}

int isEmpty(LinkedList* list)
{
  int empty = 0;
  if(list->head == NULL)
  {
    empty = 1;
  }
  return empty;
}

void enqueue(LinkedList* list, Person p)
{
  LinkedListNode* newNode = (LinkedListNode*)malloc(sizeof(LinkedListNode));
  newNode->data = p;
  if (isEmpty(list))
  {
    list->head = list->tail = newNode;
  } else
  {
    LinkedListNode* first = list->head;
    first->previous = newNode;
    newNode->next = list->head;
    list->head = newNode;
  }
  list->count ++;
}

Person dequeue(LinkedList* list)
{
  LinkedListNode* temp;
  temp = list->tail;
  list->tail = list->tail->previous;
  list->count --;

  return temp->data;
}

void viewQueue(LinkedList* list)
{
  LinkedListNode* current;
  current = list->head;
  while (current != NULL)
  {
    printf("Name: %s Birthdate: %s\n", current->data.name, current->data.birthdate);
    current = current->next;
  }
  printf("\nPeople: %d\n", list->count);
}

这是我的头文件...

#ifndef LINKED_LIST
#define LINKED_LIST

#define FALSE  0
#define TRUE !FALSE

typedef struct{
  char name[20];
  char birthdate[10];
} Person;

typedef struct LinkedListNode{
  Person data;
  struct LinkedListNode* next;
  struct LinkedListNode* previous;
} LinkedListNode;

typedef struct{
  LinkedListNode* head;
  LinkedListNode* tail;
  int count;
} LinkedList;

void createQueue(LinkedList* list);
int isEmpty(LinkedList* list);
void enqueue(LinkedList* list, Person p);
Person dequeue(LinkedList* list);
void viewQueue(LinkedList* list);

#endif

我也有这个方法来测试我的队列。当我运行它时,我得到一个分段错误。我的程序有什么问题?

#include <stdio.h>
#include "queue.h"

int main(void)
{
  LinkedList* list;
  createQueue(list);
  Person p1 = {"J Cole", "28/01/1985"};
  Person p2 = {"Kendrick Lamar", "19/01/1994"};
  Person p3 = {"Slim Shady", "17/10/1972"};
  Person p4 = {"Tupac Shakur", "12/09/1971"};

  enqueue(list, p1);
  enqueue(list, p2);
  enqueue(list, p3);
  enqueue(list, p4);

  viewQueue(list);
  return 0;
}

【问题讨论】:

  • “我认为它来自我的入队方法”。你的调试没有准确地告诉你吗?调试器将在几秒钟内完成。
  • 发布的代码无法编译。编译时,始终启用所有警告然后修复这些警告。这两个警告特别重要: 1) 警告参数 'list' 已设置但未使用 [-Wunused-but set-parameter] 在函数 createQueue() 2) 警告 'list' 在此函数中未初始化使用 [-Wuninitialized] 在函数中:main() 所以贴出的代码不能干净地编译(这些是严重的警告) 注意:当想要修改指针指向的位置时,从被调用的函数中,指针必须传递为“createQueue(&amp;list) 并且该函数必须是也修改了
  • 在调用任何“堆”内存分配函数(malloc、calloc、realloc)时 1) 不强制转换返回值,它的类型为:void*,因此可以分配给任何其他指针. 2) 始终检查 (!=NULL) 返回值以确保操作成功。
  • 在定义struct 时始终包含tag name,因为许多调试器在不使用选项卡名称的情况下无法显示各个字段。将typedef 声明与通过typedef 重命名的对象的定义分开是一种很好的编程习惯@
  • 发布的代码包含几个“神奇”数字。 “魔术”数字是没有基础的数字。在这种情况下,10 和 20。“神奇”数字使代码更难以理解、调试和维护。建议使用enum 语句或#define 语句为这些“神奇”数字赋予有意义的名称,然后在整个代码中使用这些有意义的名称。

标签: c linked-list segmentation-fault queue coredump


【解决方案1】:

当将值(如指针)传递给例程时,为了让例程设置该值,您必须传递其地址。因此,这一行:

createQueue(list);

应该是:

createQueue(&list);

如果您希望 createQueue 设置变量的值。您还需要:

void createQueue(LinkedList** list)
{
    *list = (LinkedList*) calloc(1, sizeof(LinkedList));
}

别担心——每个 C 程序员都会在某些时候犯这个错误。更多信息,请搜索“按值或引用传递”和“c 指针指向指针”。

【讨论】:

    【解决方案2】:

    您正在传递列表指针的值。您需要传递引用。

    void createQueue(LinkedList** list)
    {
      *list = (LinkedList*)calloc(1, sizeof(LinkedList));
    }
    

    而从主要的

    createQueue(&list);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 2017-01-26
      相关资源
      最近更新 更多