3

基本的には、リンクリストを使用してキューを実装し、1日の間に店に並んでいる人をシミュレートし、前の人が仕事を終えるまで待ちます。最初の数人は問題なく通過しますが、デキューの2番目の呼び出しに到達すると、segfaultが発生します。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;
         }

事前のおかげで、セグメンテーション違反が発生する可能性のある場所に関して皆さんが提供できる支援は素晴らしいでしょう。

PSIは、必要に応じてより多くの情報を提供できます。

4

3 に答える 3

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

トーマス、あなたのコメントに応えて:

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;
    }
}
于 2013-03-26T02:16:32.873 に答える
0

コメントをいただきましたが、問題の可能性が高いと思いますので、拡大していきます。

関数はポインタdequeueをリセットしません。tailこの関数はこれを使用してキューが空かどうかを判断するためenqueue、キューを空にしてからアイテムを再度入れると問題が発生します(headNULLになるため)。

于 2013-03-26T02:17:41.383 に答える
0

デキューに条件を入れますif(!head)return; 最初の行として。提案されたように、あなたはその後設定されます。

于 2013-03-26T02:21:56.313 に答える