【问题标题】:SegFaulting with a dequeue function具有出队功能的 SegFaulting
【发布时间】:2013-03-15 17:14:22
【问题描述】:

基本上,我正在使用链表实现一个队列,以尝试模拟一天中在商店排队的人,他们一直等到前面的人完成他们的工作。前几个人很好,但是当我第二次调用 dequeue 时,它​​会出现段错误。 gdb 调试器说错误来自这一行 head=current->next; (其中 current=head)。

这是我的出队函数:

    void BankQueue::dequeue()
   {
      Node* current=head;
      head=current->next;
      if(head!=NULL)
      {
            head->prev=NULL;
      }
      delete current;
   }

这是入队函数(以防我入队时导致内存泄漏):

    void BankQueue::enqueue(Customer s)
    {
         Node* node= new node;
         node->data=s;
         node->next=NULL;
         if(tail==NULL)
         {
              head=node;
              tail=node;
              node->prev=NULL;
         }
         else
         {
              node->prev=tail;
              tail->next=node;;
              tail=node;
         }

你们能提供的任何关于段错误可能发生在哪里的帮助都会很棒,在此先感谢。

P.S.I 可以在必要时提供更多信息。

【问题讨论】:

  • 你有没有在 Node 的析构函数中做任何有趣的事情?我看到的唯一一件事是,在dequeue 函数(此处:head=current->next;)中使用它之前,您没有检查headcurrent)是否为NULL。如果在空队列上出队,这将出现段错误。 编辑:啊,我认为这是问题所在,因为dequeue 不会重置enqueue 使用的tail 指针。

标签: c++ linked-list segmentation-fault


【解决方案1】:

您的dequeue 函数存在缺陷。看看如果head 变成NULL 会发生什么:

void BankQueue::dequeue()
{
    // current == NULL
    Node* current = head;
    // Setting head to NULL->next
    // This will reference memory location 0x00000000 + (some offset)
    head=current->next;
    // This is undefined, but it most likely will return true
    if(head!=NULL)
    {
        // undefined
        head->prev=NULL;
    }
    // Delete NULL
    delete current;
}

另外,是的,tail 也需要在那里更新。

// After you've made sure that head is valid
if (head == tail) {
    // there is only node, so we just clear tail
    tail = NULL;
}
// Then you proceed with removal

Thomas,回应您的评论:

void BankQueue::dequeue()
{
    // If the queue has instances
    if (head)
    {
        // If there is only one instance
        if (head == tail)
        {
            tail = NULL;
        }

        // set the new head
        head = head->next;
        // delete the old head if it exists
        if (head->prev)
        {
            delete head->prev;
        }
        // null data
        head->prev = NULL;
    }
}

【讨论】:

  • 所以我想把 if(head==tail) 放在哪里?另外,我是否需要将 head=current->next 放在 if(head!=NULL) 中?
【解决方案2】:

我有一个评论,但我会扩展,因为我认为这很可能是问题所在。

您的dequeue 函数不会重置tail 指针。因为enqueue函数使用这个来判断队列是否为空,如果你清空队列然后再往里面放项目就会有问题(因为head会是NULL)。

【讨论】:

  • 是的,当你出列时发现新的headNULL,你还必须将tail设置为NULL。这对你来说应该是有意义的,因为如果没有头,就没有尾巴。
【解决方案3】:

在 dequeue 中设置条件 if(!head) return;作为第一行。正如建议的那样,您将在此之后设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 2021-12-01
    • 2015-11-13
    • 2016-06-08
    • 2021-01-29
    相关资源
    最近更新 更多