【问题标题】:C++ delete errorC++ 删除错误
【发布时间】:2014-10-25 05:08:45
【问题描述】:

我是 C++ 新手,我正在尝试编写基于链表的队列。我的测试程序运行良好,直到我将删除添加到出队功能。然后我得到错误: ma​​lloc: 对象 0x7f8a61403a00 的 *** 错误:未分配被释放的指针

任何帮助将不胜感激。

#include <string>
#include "queue.h"
#include <iostream>
using namespace std;


Queue::Queue() { // Constructs a new empty queue.
    current_size = 0;   // number of elements in queue
    front_p = NULL; // first element in queue
    back_p = NULL;  // last element in queue
}

Queue::Queue( const Queue& q ) {// Copy constructor.
    // nothing to copy if queue empty
    if (q.current_size == 0) {
        return;
    }
    // queue not empty
    else {
        node * p = q.front_p;
        node * n;
        // assign front pointer
        n = new node(p -> data, NULL);
        front_p = n;
        p = p -> next;
        // middle elements
        while (p -> next != NULL) {
            n -> next = p;
            n = new node(p -> data, NULL);
            p = p -> next;
        }
        // assign back pointer
        n = new node(p -> data, NULL);
        back_p = n;
        current_size = q.current_size;
    }
}

void Queue::enqueue( int item ) { // Enqueues <item> to back
    node * n = new node(item, NULL);

    // first item in queue, front & back ptrs point to same element
    if (back_p == NULL) {
        front_p = n;
        back_p = n;
    }
    else {
        back_p -> next = n;
        back_p = n;
    }
    current_size++;
}

int Queue::dequeue() { // removes and returns the front item.
    // empty queue
    if (current_size == 0) {
        return -1;
    }

    int item = front();
    node * p = front_p;
    if (current_size == 1) {
        front_p = NULL;
        back_p = NULL;
        delete p;
        current_size--;
        return item;
    }
    else {
        front_p = front_p -> next;
        delete p;
        current_size--;
        return item;
    }
}

测试文件

//test  file
#include <iostream> 
#include "queue.h"
using namespace std;

int main(void) {
    Queue q1;
    cout << "Create a new queue q1" << endl;
    cout << "Size of q1 \t" << q1.size() << endl;
    cout << "Is q1 empty? \t" << q1.empty() << endl;
    cout << endl << endl;
    cout << "enqueue \t1,2,3,4,5" << endl;
    q1.enqueue(1);
    q1.enqueue(2);
    q1.enqueue(3);
    q1.enqueue(4);
    q1.enqueue(5);
    cout << "front of q1 \t" << q1.front() << endl;
    cout << "size of q1 \t" << q1.size() << endl << endl;

    cout << "q2 is a deep copy of q1" << endl;
    Queue q2(q1);
    cout << "front of q2 \t" << q2.front() << endl;
    cout << "size of q2 \t" << q2.size() << endl << endl;

    cout << "removed 4 from q1" << endl;
    q1.remove(4);
    cout << "removed 2 from q2" << endl;
    q2.remove(2);
    cout << endl;

    cout << "print out remaining elements of q1" << endl;
    int N = q1.size();
    for(int i=0; i < N; i++) {
        cout << q1.dequeue() << " ";    
    }
    cout << endl << endl;
    cout << "print out remaining elements of q2" << endl;
    N = q2.size();
    for(int i=0; i < N; i++) {
        cout << q2.dequeue() << " ";
    }
    cout << endl;
}

头文件

    class Queue
    {
    public:

        Queue(); // Constructs a new empty queue.
        Queue( const Queue& q );// Copy constructor.
        ~Queue();// Destructor.

        void enqueue( int item ); // Enqueues <item>.
        int dequeue();  // Dequeues the front item.
        int front();  // Returns the front item without dequeuing it.
        bool empty();  // Returns true iff the queue contains no items.
        int size();  // Returns the current number of items in the queue.
        bool remove(int item); // If <item> occurs in the queue, removes the 
      // first occurrence of <item> and returns true; otherwise returns false.

    private:
        class node  // node type for the linked list 
        {
       public:
           node(int new_data, node * next_node){
              data = new_data ;
              next = next_node ;
           }
           int data ;
           node * next ;
    };

    node * front_p ; // pointer to the (node containing the) next item 
              //  which to be dequeud, or NULL if the queue is empty.

    node * back_p ; // pointer to the (node containing the) last item 
              // which was enqueued, or NULL if the queue is empty.

    int current_size ; // current number of elements in the queue.
};

【问题讨论】:

  • I'm new to C++ and I'm trying to code a linked-list based queue C++ 新手,这是您的第一个任务?无论如何,您是否使用调试器来调试代码?你不能只是转储所有代码,让其他人为你调试。
  • Queue q2(q1); 你的Queue 复制构造函数在哪里?
  • @PaulMcKenzie - 可能是您无法爬行时尝试跑步的情况
  • 你的构造函数是否初始化front_pback_pcurrent_size
  • 相关:如果 rhs 是空队列,则不会在复制构造函数中初始化任何 Queue 成员变量。

标签: c++ linked-list queue delete-operator


【解决方案1】:

代码还有其他问题,但最直接的问题是您的复制构造函数已损坏。

在这个循环中

    while (p -> next != NULL) {
        n -> next = p;
        n = new node(p -> data, NULL);
        p = p -> next;
    }

p 是指向 source 队列 @9​​87654323@ 的元素的指针。同时,nnew 队列的一个元素。通过执行n -&gt; next = p;,您正在使新队列节点链接到源队列节点链。这会创建一个完全无意义的节点链接结构,稍后会分崩离析。

【讨论】:

  • +1这意味着当复制完倒数第二个节点时,目标队列中的next指针指向源队列中的最后一个节点,但目标队列的反向指针指向否则未引用的节点。 (当我开始发布你的链时,我正在写这篇文章,;复制它没有意义)。
  • @ssync - 您的复制构造函数真正需要做的就是 1) 初始化成员和 2),只需在循环中调用 enqueue。您无需经历所有这些指针操作的挑战:node * p = q.front_p; while (p -&gt; next){ enqueue(p-&gt;data); p = p-&gt;next;}
猜你喜欢
  • 2012-01-13
  • 1970-01-01
  • 2011-09-08
  • 2011-04-30
  • 2011-08-28
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
相关资源
最近更新 更多