简体   繁体   English

如何在 C 中实现基本队列?

[英]How can I implement a basic queue in C?

I am trying to learn data structures and I am struggling with getting this code to work.我正在尝试学习数据结构,并且正在努力使此代码正常工作。 Problem is I am getting segmentation fault(core dumped) with gcc C compiler.问题是我使用 gcc C 编译器出现segmentation fault(core dumped) It is supposed to be a queue.它应该是一个队列。 The code:编码:

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

#define STACK_SIZE 50

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

struct queue{
    int count;
    struct node * rear ,* front;
};

void create (struct queue * q) {
    q -> front = NULL;
    q -> rear = NULL;
    q -> count = 0;
}

int isempty(struct queue * q) {
    if(q -> count == 0)
        return 1;
    return 0;
}

int full(struct queue * q) {
    if(q -> count == STACK_SIZE) {
        return 1;
    }
    return 0;
}

void enqueue(struct queue * q , int x) {
    struct node * temp;
    temp = (struct node*) malloc(sizeof(struct node));

    temp -> data = x;
    temp -> next = NULL;

    if (full(q)) {
        printf("Not possible. Overflow.");
    }
    else if(isempty(q)) {
        q -> front = q -> rear = temp;
    } else {
        q -> rear -> next = temp;
        q -> rear = temp;
    }
    q -> count++;
}

int dequeue (struct queue * q) {
    struct node * p;
    p = (struct node*) malloc (sizeof(struct node));
    p = q -> front;

    if(isempty(q)) {
        printf("Not possible. Underflow.");
    } else {
        q -> front = q -> front -> next;
        q -> count--;
    }
    int x = (p -> data);
    return x;
}

int main (void) {
    struct queue *q;
    create (q);
    enqueue(q, 5);
}

The problem is most probably usage of pointers.问题很可能是指针的使用。 I've reviewed it a few times but no solution.我已经审查了几次,但没有解决方案。 Valgrind and gdb debuggers weren't much of a help, either. Valgrind 和 gdb 调试器也没有太大帮助。

As mentioned by OctaveL, in the function create you try to set the fields of the queue but the pointer passed to the function does not point to a queue, it is uninitialized.正如 OctaveL 所提到的,在 function创建中,您尝试设置队列的字段,但传递给 function 的指针未指向队列,它未初始化。 If you add the option -Wall to gcc it will actually warn you about this:如果您将选项-Wall添加到 gcc 它实际上会警告您:

$ gcc -o test -Wall test.c
test.c: In function 'main':
test.c:71:5: warning: 'q' is used uninitialized in this function [-Wuninitialized]
     create (q);
     ^~~~~~~~~~

Solution 1: Declare q as a record and pass the address of q to the function create :解决方案1:将q声明为记录并将q的地址传递给function创建

struct queue q;
create (&q);

Solution 2: Declare q as a pointer and allocate a new queue variable:解决方案2:将q声明为指针并分配一个新的队列变量:

struct queue *q;
q = malloc(sizeof *q);
create(q);

I would also advice you to rename the function create to init or clear since it doesn't create a new queue, it only initializes (or clears) it.我还建议您将 function创建重命名为initclear ,因为它不会创建新队列,它只会初始化(或清除)它。

To make memory allocation easier and to handle errors properly it is convenient to introduce two macros:为了使 memory 分配更容易并正确处理错误,引入两个宏很方便:

#define NEW_ARRAY(ptr, n) \
    (ptr) = malloc((n) * sizeof (ptr)[0]); \
    if ((ptr) == NULL) { \
        fprintf(stderr, "Memory allocation failed: %s\n", strerror(errno)); \
        exit(EXIT_FAILURE); \
    }

#define NEW(ptr) NEW_ARRAY(ptr, 1)

With these in place and if create is renamed to init you can write solution 2 as有了这些,如果create重命名为init ,您可以将解决方案 2 编写为

struct queue *q;
NEW(q);
init(q);

You didn't allocate memory for q in your main() , so it crashes when attempting to access q->front in create() .您没有在main()中为q分配 memory ,因此在尝试访问q->front中的create()时它会崩溃。

int main (void) {
    struct queue *q; // No allocation here
    ...
}

You probably wanted this, which works just fine:你可能想要这个,它工作得很好:

int main (void) {
    struct queue q;
    create (&q);
    enqueue(&q, 5);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM