双重自由或腐败 C++
Double free or corruption 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
问题是您将第一个条目两次插入到列表中,随后将其删除两次,这就是打印错误的时候。
您首先检查列表是否为空,如果是,则将新条目添加为第一个条目。
然后你比较新条目的时间和第一个条目的时间,如果是第一个就是同一个条目,然后你再次插入条目。
换句话说:你需要一个"else if":
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;
}
当队列为空时,添加第一项后你应该从 enqueue
函数 return ,没有它你使 front
指向它自己 .
解决方案:
if(front==NULL)
{ //if queue is empty
tmp->link = front;
front = tmp;
return; // <-- added
}
没有 return 你会遇到问题,因为 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){
其中return为真,很明显,time
是相等的,那么这一行
tmp->link = front;
使得 front
指向它自己,因为 tmp == front
和 front
不是 NULL。这就是为什么您的 dequeue
函数不起作用。
我收到一个奇怪的错误,即使我正在调用 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
问题是您将第一个条目两次插入到列表中,随后将其删除两次,这就是打印错误的时候。
您首先检查列表是否为空,如果是,则将新条目添加为第一个条目。
然后你比较新条目的时间和第一个条目的时间,如果是第一个就是同一个条目,然后你再次插入条目。
换句话说:你需要一个"else if":
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;
}
当队列为空时,添加第一项后你应该从 enqueue
函数 return ,没有它你使 front
指向它自己 .
解决方案:
if(front==NULL)
{ //if queue is empty
tmp->link = front;
front = tmp;
return; // <-- added
}
没有 return 你会遇到问题,因为 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){
其中return为真,很明显,time
是相等的,那么这一行
tmp->link = front;
使得 front
指向它自己,因为 tmp == front
和 front
不是 NULL。这就是为什么您的 dequeue
函数不起作用。