Я получаю странную ошибку, которая возникает, хотя я вызываю 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
как вы распределили и инициализировали свои PRecords? Есть ли веская причина, по которой вы выбираете malloc / free вместо new / delete?
Добавлен мой метод постановки в очередь, чтобы показать распределение PRecords, такое же поведение наблюдается, когда я использую удаление
@rahulchawla «В вопросе есть все требования ...» - нет, не работает. А именно не предоставляет Минимальный, полный и проверяемый пример.
В любом случае, вы создаете объект с помощью new, а затем освобождаете его с помощью free. Это неопределенное поведение (и он не вызывает деструктор ~PRecord()). Вместо этого сделайте delete tmp;.
как вы можете видеть @DanielLangr, я тоже пытался удалить, спасибо за помощь, я rafix получил решение
@rahulchawla, теперь есть несколько интересных ответов. Но в любом случае C++ - это не c. Итак, new / delete или new [] / delete [] и забудьте о malloc () / free ().





Проблема в том, что вы дважды вставляете свою первую запись в список, а затем дважды удаляете ее, и тогда печатается ошибка.
Сначала вы проверяете, пуст ли список, если да, добавьте новую запись в качестве первой. Затем вы сравниваете время новой записи со временем первой записи, которая является той же самой записью, если она первая, затем вы снова вставляете запись.
Другими словами: вам нужно «иначе, если»:
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 Конечно. Просто, с точки зрения стиля кодирования, я бы всегда использовал return, то есть не использовал бы return в первом if, а потом имел бы if .. else.
Когда очередь пуста, после добавления первого элемента вы должны вернуться из функции 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 не работает.
Спасибо за ясный и лаконичный ответ - он имеет смысл, и я действительно кое-что узнал! Очень признателен!
Почему большие пальцы вниз? В вопросе есть все требования, он ясен и лаконичен.