【问题标题】:Double free or corruption C++双重释放或损坏 C++
【发布时间】:2018-10-26 06:05:50
【问题描述】:

我得到一个奇怪的错误,即使我正在调用 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

【问题讨论】:

  • 为什么不赞成?该问题具有所有要求,并且清晰简洁。
  • 您是如何分配和初始化您的预记录的?你有正当理由选择 malloc/free 而不是 new/delete 吗?
  • 添加了我的 enqueue 方法来显示 PRecords 的分配,当我使用 delete 时会有同样的行为
  • 无论如何,您使用new 创建一个对象,然后使用free 解除分配。这是未定义的行为(它不会调用析构函数~PRecord())。请改用delete tmp;
  • @rahulchawla 现在有一些有趣的答案。但无论如何,c++ 不是 c。所以 new/delete 或 new[]/delete[] 忘记 malloc()/free()。

标签: c++ memory-management queue malloc free


【解决方案1】:

当队列为空时,在添加第一项后,您应该从 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&lt;=front-&gt;time){返回true,很明显,time是相等的,那么这一行

tmp->link = front;

使front 指向自身,因为tmp == frontfront 不为NULL。这就是为什么你的 dequeue 函数不起作用的原因。

【讨论】:

  • 感谢您简洁明了的回答 - 完全有道理,我实际上学到了一些东西!非常感谢!
【解决方案2】:

问题是您将第一个条目两次插入到列表中,随后又将其删除两次,即打印错误。

您首先检查列表是否为空,如果是,则将新条目添加为第一个条目。
然后将新条目的时间与第一个条目的时间进行比较,如果是第一个条目,则它是相同的条目,然后再次插入该条目。

换句话说:你需要一个“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;    
    }

【讨论】:

  • 感谢您的输入,这可能也有效,但我首先看到了 rafix 的回答。再次感谢您!
  • @rahulchawla 当然。只是,就编码风格而言,我将始终使用return,即在第一个if 中不使用return,之后使用if .. else
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多