【问题标题】:Clang error: pointer being freed was not allocatedClang 错误:未分配被释放的指针
【发布时间】:2015-08-18 00:06:38
【问题描述】:

我写了这个链表的实现:

template<typename T>  // implementation: Linked_list 
class Linked_list {  
    private:
        Node<T>* head;
        Node<T>* tail;
        Node<T>* current;
        int size;


        void init() 
        {
            head = tail = current = new Node<T>();
            size = 0;
        }


        Node<T>* search_previous()
        {
            if (current == head) {
                return nullptr;
            }
            Node<T>* previous_node = head;
            while (previous_node->next != current) {
                previous_node = previous_node->next;
            }
            return previous_node;
        }


    public:
        Linked_list() 
        {
            init();
        }


        void clear() 
        {
            while (head != nullptr) {
                current = head;
                head = head->next;
                delete current;

            }
            init();
        }


        ~Linked_list() 
        {
            clear();
            delete head;
        }


        void append(T p_element) 
        {
            tail->next = new Node<T>(p_element);
            tail = tail->next;
            ++size;
        }


        void insert(T p_element)
        {
            current->next = new Node<T>(p_element, current->next);
            if (current == tail) {
                tail = tail->next;
            }
            ++size; 
        }


        T remove() 
        {
            if (current->next == nullptr) {
                throw std::runtime_error("No element to remove");
            }
            T removed_element = current->next->element;
            Node<T>* temporary_pointer = current->next;
            current->next = current->next->next;
            if (temporary_pointer == tail) {
                tail = current;
            }
            delete temporary_pointer;
            --size;
            return removed_element;
        }


        T get_element() 
        {
            if (current->next == nullptr) {
                throw std::runtime_error("No element to get");
            }
            return current->next->element;
        }


        void go_to_start() 
        {
            current = head;
        }


        void go_to_end() 
        {
            current = tail;
        }


        void go_to_pos(int p_pos) 
        {
            if ((p_pos < 0) || (p_pos >= size)) {
                throw std::runtime_error("Index out of bounds");
            }
            current = head;
            for (int index = 0; index < p_pos; ++index) {
                current = current->next;
            }
        }


        void next() 
        {
            if (current != tail) {
                current = current->next;
            }
            else {
                throw std::runtime_error("There's no next positition");
            }
        }


        void previous() 
        {
            if (current != head) {
                current = search_previous();
            }
            else {
                throw std::runtime_error("There's no previous positition");
            }
        }


        int get_pos() 
        {
            int pos = 0;
            Node<T>* temporary_pointer = head;
            while (temporary_pointer != current) {
                temporary_pointer = temporary_pointer->next;
                ++pos;
            }
            return pos;
        }


        int get_size() 
        {
            return size;
        }


        void concat(Linked_list<T> p_list)
        {
            for (p_list.go_to_start(); p_list.get_pos() < p_list.get_size(); p_list.next()) {
                append(p_list.get_element());
            }
        }

};

这是节点:

template<typename T>
class Node {
    public:
        T element;
        Node<T>* next;


        Node(T p_element, Node<T>* p_next = nullptr)
        {
            element = p_element;
            next = p_next;
        }


        Node(Node<T>* p_next = nullptr)
        {
            next = p_next;
        }
};

我遇到的问题是,当我尝试使用 concat 方法时,我从 Clang 收到这条消息:

proofs(13417,0x7fff7bb9f000) malloc: * 对象 0x7fe10b603170 的错误:未分配被释放的指针 * 在 malloc_error_break 中设置断点进行调试 中止陷阱:6

我能做些什么来修复它?

【问题讨论】:

  • What can I do for fix it? 你调试你的代码。
  • void concat(Linked_list&lt;T&gt; p_list) 按值传递,而您的 Linked_list 类不遵循 3 规则。这是灾难的根源。
  • 如何通过引用传递?
  • 我已经拿到了,谢谢。
  • 声明参数为引用,则不会复制。然而,这只是解决实际问题的一种创可贴方法,那就是不应该复制课程。您应该关闭复制(您可以通过一种或两种方式执行此操作,具体取决于您是否使用 C++ 11)或为您的类提供适当的复制构造函数和赋值运算符。

标签: c++ pointers memory dynamic data-structures


【解决方案1】:

明显的错误是这样的:

    void concat(Linked_list<T> p_list)

您正在按值传递Linked_list。这意味着创建和销毁链表的临时副本。由于析构函数删除了内存,它也删除了您正在复制的链表的内存。

由于您的Linked_list 类没有用户定义的赋值运算符或复制构造函数来处理指向动态分配的内存的成员,因此无法安全地复制该类(如果您调试过,您应该已经看到析构函数被你没想到的调用了,就是临时被销毁了,从而破坏了原来的对象)。

为了防止这种情况,要么通过引用(而不是值)传递,

   void concat(Linked_list<T>& p_list)

或提供适当的复制构造函数和赋值运算符。

What is the rule of Three

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 2014-06-07
    • 1970-01-01
    • 2015-10-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多