【问题标题】:returning wrong address from pop function从 pop 函数返回错误的地址
【发布时间】:2013-10-05 02:43:19
【问题描述】:

在解决了我的结构的其他问题后,我的推送按预期工作,但是我的 pop 返回了错误的地址,我不知道为什么 -

QNode* const Q_Pop(Q* const pointerQ){

   ...       // empty check

   QNode* tempNode = pointerQ->front.next;

   pointerQ->front.next = (tempNode->next);
   tempNode->next->prev = &(pointerQ->front);

   return tempNode;
}

我相当确定我实际删除和重新链接堆栈的逻辑是正确的,但我对指针的使用和返回它们是一团糟。

结构 -

struct QueueNode {

   struct QueueNode *prev;     /* Previous list element. */
   struct QueueNode *next;     /* Next list element.    */
};

typedef struct QueueNode QNode;

struct Queue {
   QNode front;    // sentinel node at the front of the queue
   QNode rear;     // sentinel node at the tail of the queue
};

typedef struct Queue Q;

感谢您的帮助!

【问题讨论】:

  • 必须查看更多代码,但似乎pointerQ->front 可能会指向队列的头部。你会返回那个而不是下一个。但是,如果没有看到数据结构,我就无法判断。
  • 我猜你想弹出当前对象,即pointerQ->front,而不是pointerQ->front->next,这可能是你的问题。
  • 如果您可以提供一个可运行的程序并告诉您期望的输出,那么回答您的问题会更容易。 sscce.org
  • 奇怪的是pointerQ->front 不是指针。根据我对堆栈的了解,这应该是一个指针,以便您可以更改它,如果队列为空等,则设置为 NULL
  • 刚刚编辑它以提供结构代码

标签: c pointers struct stack


【解决方案1】:

您不应该使用“哨兵节点”;这是没有意义的,而且非常令人困惑。队列可以简单地表示为第一个元素的QNode*。它总是指向第一个元素;如果是NULL,则队列为空;如果element->nextNULL,则它是最后一个元素,因为没有下一个元素。使用它非常简单。

struct QueueNode {
    // stuff
    // stuff
    // stuff
    struct QueueNode* prev; // this may be optional
    struct QueueNode* next;
};
typedef struct QueueNode QNode;

void push_front(QNode** queue, QNode* pushme) {
    pushme->prev = NULL;
    pushme->next = *queue;
    (*queue)->prev = pushme;
    *queue = pushme;
}

void push_end(QNode** queue, QNode* pushme) {
    QNode* node = *queue;

    if (node) {
        while (node->next) node = node->next;
        node->next = pushme;
        pushme->prev = node;
        pushme->next = NULL;
    }
    else {
        *queue = pushme;
        (*queue)->next = (*queue)->prev = NULL;
    }
}

QNode* pop_front(QNode** queue) {
    QNode* node = *queue;

    if (node)
        *queue = node->next;

    return node;
}

QNode* pop_end(QNode** queue) {
    QNode* node = *queue;

    if (node) {
        while (node->next) node = node->next;
        if (node->prev) {
            node->prev->next = NULL;
            node->prev = NULL;
        }
        else
            *queue = NULL;
    }

    return node;
}


QNode* create_node_front(QNode** queue) {
    QNode* node = malloc(sizeof(QNode));
    push_front(queue, node);
    return node;
}

QNode* create_node_end(QNode** queue) {
    QNode* node = malloc(sizeof(QNode));
    push_end(queue, node);
    return node;
}

QNode* my_queue = NULL; // declare an empty queue
QNode* my_node = create_node_end(&my_queue); // create a new node, its already stored in the queue

我没有测试它,但它给出了一个大致的想法。

您可以使用push_front()create_node_front() 推送(无循环,最佳性能)然后使用pop_end() 弹出以产生队列效果(FIFO),或使用pop_front() 弹出以产生堆栈效果( LIFO)。

【讨论】:

  • 在明确标记为“C”而非“C++”的问题的答案中不允许引用。除此之外,它看起来不错......
  • 没有达到 C11 — 所以是的,你错了。引用是 C++ 的一个特征,并且从未成为 C 的一部分。
猜你喜欢
  • 2011-12-05
  • 2012-09-05
  • 2014-04-12
  • 2013-01-13
  • 1970-01-01
  • 2015-08-26
  • 2012-03-02
相关资源
最近更新 更多