Ошибка: вызов delete дважды в одной и той же ячейке памяти

#c #pointers #memory #delete-operator

#c #указатели #память #оператор удаления

Вопрос:

Я написал эту функцию на C как часть более крупной программы:

 Object Single_list<Object>::pop_front() {
    //Single_node<Object> *tmp_front;  
    //Object hold;
    if (empty()) {
        throw underflow();
    } 

    Single_node<Object> first_node = front();
    Single_node<Object> *ptr = list_head;                                                            
    list_head = list_head->next();  
    delete ptr;
    return first_node.retrieve();
}
  

Однако, когда я пытаюсь использовать эту функцию, я получаю следующее сообщение:

ПРЕДУПРЕЖДЕНИЕ: вызов delete дважды в одной и той же ячейке памяти: 0x100100160

Я действительно в замешательстве, я не удаляю указатель (предполагая, что это является причиной проблемы?) дважды.

Любой совет будет оценен.

Как и было запрошено, вот конструктор и функция извлечения для Single_Node, хотя я не уверен, насколько это будет полезно для ошибки, связанной с удалением, которую я получаю:

 template <typename Object>
Single_node<Object>::Single_node( const Object amp;e, Single_node<Object> *n ):element( e ), next_node( n )
{
    // empty constructor
}

template <typename Object>
Object Single_node<Object>::retrieve() const
{
    return element;
}

template <typename Object>
Single_node<Object> *Single_node<Object>::next() const
{ 
    return next_node;
}
  

Комментарии:

1. Если это действительно единственный релевантный код, то компилятор ошибается. Иногда это может быть неправильно.

2. Пожалуйста, опубликуйте какой-нибудь полный код, показывающий проблему

3. Из показанного кода проблема, по-видимому, заключается в том, что вы возвращаете объект, сохраненный first_node после его удаления (предполагая, что list_head и front() возвращают одно и то же). Хотя трудно сказать, не зная семантики Single_node.

4. Это не может быть ошибкой компилятора..

5. Это не ошибка, это предупреждение.

Ответ №1:

Основываясь на комментарии Манкарса, попробуйте следующее:

 Object Single_list<Object>::pop_front() {

    if (empty()) {
        throw underflow();
    } 

    Object result = front().retrieve();

    Single_node<Object> *ptr = list_head;
    list_head = list_head->next();  
    delete ptr;
    return resu<
}
  

Это захватывает результат с первого узла, прежде чем он будет удален.

Комментарии:

1. Привет, спасибо за ответ, но я уже сохраняю содержимое узлов в переменной hold, а затем возвращаю эту переменную hold. Таким образом, удаление узла не должно влиять на возвращаемое значение…

2. @rr — У Single_node есть деструктор? Что это дает?

3. @rr: Вы уверены, что это = выполняет глубокое копирование? И мне действительно интересно, что Object такое; если вы храните это в Single_node значении be вместо ссылки, то Object это не может быть полиморфным … и название подразумевает, что это так.

4. @Mike DeSimone: Объект может быть любым, потому что это шаблон type:template <typename Object> Object Single_list<Object>::pop_front()....

5. @Bo Persson: У Single_node нет деструктора, но у SingleList есть, где я просто делаю pop_front, пока список не пуст. while (!empty()){ pop_front(); }