【问题标题】:What's wrong in this queue implementation?这个队列实现有什么问题?
【发布时间】:2016-09-09 13:27:14
【问题描述】:

以下是我的队列实现。我的队列只是一个由两个 qnode 组成的数组:头部和尾部。 enqueue 和 dequeue 应该处理内部队列实现。

在我用不同的整数调用 enqueue 后,Q[0].next == Q[1].next 的输出为 1。我无法找出错误。

struct Qnode{
int index;
struct Qnode *next;
};
typedef struct Qnode qnode;

qnode* makeQueue(){
     qnode *Q;
     Q = (qnode *) malloc(2*sizeof(qnode));
     qnode head,tail;
     head.next = NULL;
     tail.next = NULL;
     head.index = 0;
     tail.index = -1;
     Q[0] = head;
     Q[1] = tail;
     return Q;
}

void enQueue(qnode *Q, int index){
    qnode node,head = Q[0], rear = Q[1];
    node.index = index;
    node.next = NULL;
    if(head.next == NULL && rear.next == NULL){
        head.next = &node;
        rear.next = &node;
    }
    else{
        (rear.next)->next = &node;
        rear.next = &node;
    }
    Q[0].index = head.index + 1;
}

谢谢

【问题讨论】:

  • malloc(2*sizeof(qnode)); ?
  • 因为 Q 本身将是 2 个 qnodes 的数组
  • 首先,它不会是2个节点的array,而是链表,你只需要head节点指向第一个节点或NULL。您的 enqueue 函数应根据需要分配节点。 Example.
  • 如果在makeQueue 之后调用enQueue,由于rear.next == -1(rear.next)->next = &node;UB
  • 您将 Q[0] 的值复制到 head 变量中,然后修改该变量的值。这不会反映在 Q[0] 中。您应该使用指针 *head 进入 Q[0] 或者只是将其用作 Q[0].whatever

标签: c pointers queue


【解决方案1】:

enQueue 函数有问题

qnode node,head = Q[0], rear = Q[1];
node.index = index;
node.next = NULL;
if(head.next == NULL && rear.next == NULL){
    head.next = &node;
    rear.next = &node;
}

上面的代码是分配给head.nextrear.next一个局部范围变量的地址:即堆栈分配的变量。

node 变量只会存在到函数结束。所以指向这些指针的地址在函数外部无效:在函数外部访问它是非法的,Undefined Behavior

此外,对该函数所做的所有修改都不会反映到 Q 数组:您正在修改数组元素的本地范围副本。

【讨论】:

  • 哦,我明白了。我尝试将节点更改为 qnode* 节点。问题依然存在
  • 您应该重新考虑所有代码。这种方式是错误的,而不是你需要的。你必须(我猜)实现一个链表,而不是一个包含 2 个元素的数组来保存数据。
  • 我认为第二个问题是我对作为局部变量的头部和尾部进行了更改。该代码现在有效。谢谢
猜你喜欢
  • 1970-01-01
  • 2021-10-17
  • 2011-09-28
  • 2011-12-14
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多