Двойное освобождение или коррупция C++

Я получаю странную ошибку, которая возникает, хотя я вызываю free (), используется метод dequeue, который удаляет элементы из очереди с приоритетом, функциональность работает нормально, но когда очередь пуста, ошибка выдается вместо сообщение об ошибке, которое определено.

Код и ошибка ниже:

void enqueue(string item, long time)
    {
        cout<<"Please Enter Entry and Time of element you wish to enqueue.."<<endl;
        PRecord *tmp, *q;
        tmp = new PRecord;
        tmp->entry = item;
        tmp->time = time;
        if (front==NULL){ //if queue is empty
            tmp->link = front;
            front = tmp;    
        }
        if (time<=front->time){ //if newer priority item comes through put it at front of queue
            tmp->link = front;
            front = tmp;    
        }

        else {
            q = front;
            while (q->link != NULL && q->link->time <= time)
                q=q->link;
            tmp->link = q->link;
            q->link = tmp;


        }
                   }

int dequeue()
        {try{
            PRecord *tmp; //pointer to front of queue

            if (front!=NULL){
                tmp = front;
                cout<<"Deleted item is: "<<endl;
                displayRecord(tmp); //outputs record details
                front = front->link; //link to the front

                free(tmp); //dealloc memory no longer used


            }
            else{
            cerr<<"Queue is empty - No items to dequeue!"<<endl;    
                }
        } catch(...){
            return(0);
        }

            }





*** glibc detected *** ./3x: double free or corruption (fasttop): 0x0000000000bb3040 ***
======= Backtrace: =========
/lib64/libc.so.6[0x35a8675dee]
/lib64/libc.so.6[0x35a8678c3d]
./3x[0x401275]
./3x[0x400f69]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x35a861ed1d]
./3x[0x400d59]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:06 2623369                            /home/std/rc14lw/lab5excercisefinal/3x
00601000-00602000 rw-p 00001000 08:06 2623369                            /home/std/rc14lw/lab5excercisefinal/3x
00bb3000-00bd4000 rw-p 00000000 00:00 0                                  [heap]
35a8200000-35a8220000 r-xp 00000000 08:01 1310722                        /lib64/ld-2.12.so

Почему большие пальцы вниз? В вопросе есть все требования, он ясен и лаконичен.

rahulchawla 26.10.2018 08:24

как вы распределили и инициализировали свои PRecords? Есть ли веская причина, по которой вы выбираете malloc / free вместо new / delete?

Christophe 26.10.2018 08:33

Добавлен мой метод постановки в очередь, чтобы показать распределение PRecords, такое же поведение наблюдается, когда я использую удаление

rahulchawla 26.10.2018 08:36

@rahulchawla «В вопросе есть все требования ...» - нет, не работает. А именно не предоставляет Минимальный, полный и проверяемый пример.

Daniel Langr 26.10.2018 08:49

В любом случае, вы создаете объект с помощью new, а затем освобождаете его с помощью free. Это неопределенное поведение (и он не вызывает деструктор ~PRecord()). Вместо этого сделайте delete tmp;.

Daniel Langr 26.10.2018 08:52

как вы можете видеть @DanielLangr, я тоже пытался удалить, спасибо за помощь, я rafix получил решение

rahulchawla 26.10.2018 08:58

@rahulchawla, теперь есть несколько интересных ответов. Но в любом случае C++ - это не c. Итак, new / delete или new [] / delete [] и забудьте о malloc () / free ().

Christophe 26.10.2018 09:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
589
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема в том, что вы дважды вставляете свою первую запись в список, а затем дважды удаляете ее, и тогда печатается ошибка.

Сначала вы проверяете, пуст ли список, если да, добавьте новую запись в качестве первой. Затем вы сравниваете время новой записи со временем первой записи, которая является той же самой записью, если она первая, затем вы снова вставляете запись.

Другими словами: вам нужно «иначе, если»:

    if (front==NULL){ //if queue is empty
        tmp->link = front;
        front = tmp;    
    } else if (time<=front->time){ //  <-- there is the else you need to add
        tmp->link = front;
        front = tmp;    
    }

спасибо за вклад, это может сработать, но сначала я увидел ответ rafix. Еще раз, спасибо!

rahulchawla 26.10.2018 09:06

@rahulchawla Конечно. Просто, с точки зрения стиля кодирования, я бы всегда использовал return, то есть не использовал бы return в первом if, а потом имел бы if .. else.

Rene 26.10.2018 09:11
Ответ принят как подходящий

Когда очередь пуста, после добавления первого элемента вы должны вернуться из функции enqueue, без этого вы делаете этот frontуказывает на себя.

Решение:

       if (front==NULL)
       {   //if queue is empty
            tmp->link = front;
            front = tmp;    
            return; // <-- added
        }

Без возврата у вас возникнет проблема, потому что front указывает на себя:

Этими строками вы создаете первый элемент:

tmp = new PRecord;
tmp->entry = item;
tmp->time = time;
if (front==NULL){ //if queue is empty
    tmp->link = front;
    front = tmp;    
}

затем вы проверяете следующее условие if (time<=front->time){, которое возвращает истину, очевидно, что time равны, тогда эта строка

tmp->link = front;

делает, что front указывает на себя, потому что tmp == front и front не равны NULL. Вот почему ваша функция dequeue не работает.

Спасибо за ясный и лаконичный ответ - он имеет смысл, и я действительно кое-что узнал! Очень признателен!

rahulchawla 26.10.2018 09:00

Другие вопросы по теме