Двойное освобождение или коррупция C ++ - PullRequest
0 голосов
/ 26 октября 2018

Я получаю странную ошибку, которая возникает, даже несмотря на то, что я вызываю 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

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Когда очередь пуста, после добавления первого элемента вы должны вернуться из функции 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){, которое возвращает true, очевидно, time равны, тогда эта строка

tmp->link = front;

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

0 голосов
/ 26 октября 2018

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

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

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

    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;    
    }
...