【问题标题】:Implementing a queue using an existing implementation of a linked list: Bad File Number error使用链表的现有实现实现队列:错误文件号错误
【发布时间】:2016-07-02 04:50:13
【问题描述】:

我已经获得了一些现有的 C 代码(一个头文件和一些源代码)来实现一个链表,并被赋予了一个任务来使用它来实现一个队列。

这是我得到的头文件的一部分以及相关的功能描述:

/* List is a pointer to a list_t struct */
typedef struct list_t* List;

struct list_t {
    void *data;
    List next;
};

/* Pushes data as the new head of list. May be used to create a new list:
 * new_list = push(NULL, data) */
extern List push(List list, void *data);

/* Pop the head off the list */
extern void *pop(List *list);

/* Return the length of the list */
extern int len(List list);

/* Returns a reversed copy of list */
List reverse(List list);

/* Prepend data to list and update list */
extern List prepend(List *list, void *data);

/* Append l1 to the end of l2 */
void append(List l1, List *l2);

/* Inserts data into the tail of list */
void insert(void *data, List *list);

/* Inserts data into the tail of list or position equal to the next element     */
void insert_by(bool (*eq)(void *data, void *node), void *data, List *list);

/* Inserts data into the tail of list. Returns true if sucessful,
 * false if it finds an element already equal to data */
bool insert_if(bool (*eq)(void *data, void *node), void *data, List *list);

/* Returns the node equal to aim in list, returns NULL if not found */
extern List find(bool (*eq)(void *aim, void *node), void *aim, List list);

/* Removes and returns the element equal to aim in list,
 * returns NULL if not found */
extern void *del(bool (*eq)(void *aim, void *node), void *aim, List *list);

/* Returns a new list that passes the predicate p */
List filter(bool (*p)(void *data), List list);

/* Print list to f by applying print to each node that is not NULL */
extern void print_list(void (*print)(FILE *f, void *data), FILE *f, List node);

/* Free the memory allocated to each list node */
extern void free_list(List node);

我知道为了实现一个队列,我至少需要两个函数,enqueue()dequeue()。我继续使用上述头文件中的 List 类型创建了自己的头文件,其中包含这些函数和队列的 typedef:

//Queue.h
#include "list.h"

typedef List Queue;

//Add item to queue...
void enqueue(Queue q, void *data);

//removes and returns an item from the queue...
void dequeue(Queue *q);

然后我继续在queue.c 中实现源代码。我现在只实现了enqueue,因为我想确保它在继续之前有效:

#include "queue.h"

void enqueue(Queue q, void *data){
    if (q == NULL){
        q = push(q, data);
    }
    else {
        insert(data, &q);
    }
}

真的很简单,我知道。我打算用下面的文件main.c来测试队列:

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

int main(int argc, char **argv){
    Queue q = NULL;
    int i;
    for (i = 0; i < 10; i++){ enqueue(q, &i); } //one line for brevity
    return 0;
}

此时我没想到在运行main.c 时会看到任何输出,我所期望的只是程序运行时没有错误然后停止。一切都编译得很好,但是当我运行 main.c 时,我得到的只是:

sh: ./main.exe: bad file number

这是什么意思,任何人都可以找出可能导致此问题的原因吗?

编辑:源代码是这样编译的:

gcc -c list.c
gcc -c queue.c
gcc -c main.c -o main.exe

【问题讨论】:

  • 可以这样编译吗--> gcc list.c queue.c main.c -o main.exe

标签: c data-structures linked-list queue


【解决方案1】:

您的 enqueue 函数违反了 push 方法的约定。

push方法返回新的头部。

你需要:

Queue enqueue(Queue q, void *data){
    return push(q, data);
}

在您的电话中:

for (i = 0; i < 10; i++){ 
    q = enqueue(q, &i); 
}

请注意,这将在每次迭代时推送相同的指针。如果您更改i,您将更改队列中每个节点的值。这可能不是你想要的!

还要注意,对本地(自动)变量的地址进行排队可能是一件坏事,并且当变量超出范围时可能会导致堆栈问题。 (在您的情况下,imain 中声明,因此在程序结束之前它不会超出范围。)

【讨论】:

  • 我继续并更改了enqueue 函数,但它仍然没有将元素添加到队列中。你能看出问题吗?
  • 当添加第一个元素时,queses 的头部从 NULL 变为第一个 Queue 项。您需要以某种方式更新队列指针。我建议你返回新地址,但你还没有这样做,所以在main 中,q 的值永远不会改变初始的NULL 值。
【解决方案2】:

这不仅仅与 C 编程问题有关,还与未正确调用的编译器命令有关。

您的编译命令不完整。

使用这个:

gcc -c list.c
gcc -c queue.c
gcc -c main.c
gcc list.o main.o queue.o -o main.exe
./main.exe

解释:

gcc -c list.c                           produces list.o
gcc -c queue.c                          produces queue.o
gcc -c main.c                           produces main.o
gcc list.o main.o queue.o -o main.exe   invokes the linker that links the .o files
                                        together producing main.exe

./main.exe                              run the program

您的 C 代码中可能存在其他与编程相关的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    相关资源
    最近更新 更多