为什么我在`./a.out'中出现***错误:损坏的双链表:0x0000000001c8a000 ***来自插入函数?

时间:2017-11-18 15:45:30

标签: c++ heap heap-memory priority-queue heap-corruption

因此,当使用二进制堆实现最小优先级队列时,我收到此错误语句(在我的程序完全编译并正确运行main之后)。调试后我相信我发现它是由我的插入函数引起的,或者更具体地说是

  

的push_back(元件)

在BinaryHeap.cpp中的insert函数中。

我的印象是这个错误是由堆溢出引起的,但是我使用了一个向量来实现我的堆(当使用int而不是struct项时它起作用)所以它应该/正在分配内存为需要。有人可以向我解释为什么我得到这个奇怪的错误陈述以及如何解决它?谢谢

这是我的两个头文件和我的主文件,以及完整的错误声明

BinaryHeap.h

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <iterator>
#include <stdexcept>
#include <sstream>
using namespace std;
struct EmptyHeap : std::range_error {
      explicit EmptyHeap(char const* msg=NULL): range_error(msg) {}
    };

struct data {
   int jobID;
   int length;
   int priority;
};

struct item {
   int value; //Priority 
   int key;
};

/*
 * Class Declaration
 */
class BinaryHeap
{
private:
   vector <item> v1;
   int left(int parent);
   int right(int parent);
   int parent(int child);
   void heapifyup(int index);
   void heapifydown(int index);
public:
   BinaryHeap() {}
   ~BinaryHeap();
   bool is_empty();
   void insert(item element);
   void remove_min();
   item findMin();
   void print();
   int length();
};

BinaryHeap::~BinaryHeap() //DONE
{   
while (!is_empty())
    v1.pop_back();

}

bool BinaryHeap::is_empty() { //DONE
    if (v1.size() == 0)
        return true;
    else
        return false;
}


/*
 * Return Heap Size
 */

int BinaryHeap::length() //DONE
{
    return v1.size();
}

/*
 * Insert Element into a Heap
 */
void BinaryHeap::insert(item element) //DONE
{
    v1.push_back(element); //The error is coming from this
    heapifyup(v1.size()-1);
}
/*
 * Delete Minimum Element
 */
void BinaryHeap::remove_min() //DONE
{
    if (is_empty())
    {
        throw EmptyHeap("Empty Heap");
    }
    cout << "Element Deleted: " << "(" << v1[0].key <<"," << v1[0].value << ") " << endl;
    v1[0] = v1.at(v1.size() - 1);
    v1.pop_back();
    heapifydown(0);
}

/*
 * Extract Minimum Element
 */
item BinaryHeap::findMin() //DONE
{
    if (is_empty())
        throw EmptyHeap("Empty Heap");
    else
        return v1.front();
}

/*
 * Display Heap
 */
void BinaryHeap::print() //DONE
{
    int pos = 0;
    cout<<"Heap (Key, Value) -->  ";
    for (int pos = 0; pos < v1.size(); pos++) {
        cout<< "(" << v1[pos].key <<"," << v1[pos].value << ") ";
    }
    cout<<endl;
}

/*
 * Return Left Child
 */
int BinaryHeap::left(int parent)
{
    int l = 2 * parent + 1;
    if (l < v1.size())
        return l;
    else
        return -1;
}

/*
 * Return Right Child
 */
int BinaryHeap::right(int parent)
{
    int r = 2 * parent + 2;
    if (r < v1.size())
        return r;
    else
        return -1;
}

/*
 * Return Parent
 */
int BinaryHeap::parent(int child)
{
    int p = (child - 1)/2;
    if (child == 0)
        return -1;
    else
        return p;
}

/*
 * Heapify- Maintain Heap Structure bottom up
 */
void BinaryHeap::heapifyup(int in) //in = index DONE I BELIEVE
{
    if (in >= 0 && parent(in) >= 0 && v1[parent(in)].key > v1[in].key)
    {
        item temp = v1[in];
        v1[in] = v1[parent(in)];
        v1[parent(in)] = temp;
        heapifyup(parent(in));
    }
}

/*
 * Heapify- Maintain Heap Structure top down
 */
void BinaryHeap::heapifydown(int in) //in = index DONE I BELIEVE
{
    int child = left(in);
    int child1 = right(in);
    if (child >= 0 && child1 >= 0 && v1[child].key > v1[child1].key)
    {
       child = child1;
    }
    if (child > 0 && v1[in].key > v1[child].key)
    {
        item temp = v1[in];
        v1[in] = v1[child];
        v1[child] = temp;
        heapifydown(child);
    }
}

vector<data> readData(string fileName)
{
    ifstream ist;
    ist.open(fileName.c_str());
    if (!ist) {
        cerr << "Error in opening the file" << std::endl;
    }
    vector<data> datas;
    vector<data> tempdatas;

    char delim = ',';
    string line;

    while(getline(ist,line)) {
        stringstream ss(line);
        string str;
        data temp;
        int i = 0;
        int dataNum = 0;
        for (int i = 0; i < 3; i++) {
            getline(ss,str,delim);
            dataNum = atoi(str.c_str()); //Convert String to int
            if (i == 0) {
                temp.jobID = dataNum;
                }
            else if (i == 1) {
                temp.length = dataNum;
                }
            else {
                temp.priority = dataNum;
            }
        }
        tempdatas.push_back(temp);
    }
    for (int j = 1; j < tempdatas.size();j++) {
        datas.push_back(tempdatas[j]);
    }

    return datas;
}


vector<item> dataToItems(vector<data> datas, string type)
{
    vector<item> items;
    for (int i = 0; i < datas.size(); i++) {
        if (type == "jobID") {
            item temp;
            temp.value = datas[i].jobID;
            temp.key = datas[i].priority;
            items.push_back(temp);
        }
        else if (type == "length"){
            item temp;
            temp.value = datas[i].length;
            temp.key = datas[i].priority;
            items.push_back(temp);
        }
        else {
            cout << "Not a possible type" << endl;
            break;
        }
    }
    return items;
}

MinPriorityQueue.h

#include "BinaryHeap.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <iterator>
#include <stdexcept>
#include <sstream>
using namespace std;

struct EmptyMinPriorityQueue : std::range_error {
  explicit EmptyMinPriorityQueue(char const* msg=NULL): range_error(msg) {}
};

class MinPriorityQueue {
private:
    BinaryHeap bh;
public:
    MinPriorityQueue() : bh() { } // constructor FIX
    ~MinPriorityQueue() { bh.~BinaryHeap(); } // destructor
    bool isEmpty() {return bh.is_empty();} //tests if P is empty
    void insertItem(item kx); //inserts a key k and value x into P
    int size() {return bh.length();}
    item minElement() {return bh.findMin();} //returns an entry with the smallest key in P
    void removeMin(); //removes an entry with the smallest key in P
    int minKey() {return bh.findMin().key;} //returns the smallest key in P
    void print();

};

void MinPriorityQueue::insertItem(item kx) {
    bh.insert(kx);
}

void MinPriorityQueue::removeMin() {
    bh.remove_min();
}

void MinPriorityQueue::print() {
    bh.print();
}

Main.cpp的

#include "MinPriorityQueue.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <iomanip>
using namespace std;

int main() { //It is only ordered/sorted in the sense that the first element is the least, the rest are "ordered" when needed.
    MinPriorityQueue MPQ;

    vector<data> DataSetSize10 = readData("DataSetSize10.csv"); //Working on descen10 file
    vector<item> ItemSetSize10 = dataToItems(DataSetSize10, "jobID");

    vector<item> test;
    cout << "Insert all JobID Data into Binary Heap from DataSetSize10.csv" << endl;
    for (int i=0; i < ItemSetSize10.size(); i++) {
        MPQ.insertItem(ItemSetSize10[i]); //This is causing my error
    }
    MPQ.print();
    cout << endl;
    cout << "Remove min and print new MPQ" << endl;
    MPQ.removeMin();
    MPQ.print();
    cout << endl;

    return 0;
}

打印的内容(包括错误声明)

Insert all JobID Data into Binary Heap from DataSetSize10.csv
Heap (Key, Value) -->  (-16,2) (-3,9) (-16,4) (-3,10) (8,7) (15,6) (-3,8) (11,1) (3,3) (11,5)

Remove min and print new MPQ
Element Deleted: (-16,2)
Heap (Key, Value) -->  (-16,4) (-3,9) (-3,8) (-3,10) (8,7) (15,6) (11,5) (11,1) (3,3)

*** Error in `./a.out': corrupted double-linked list: 0x0000000001f54000 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7ab54)[0x7f7304512b54]
/lib64/libc.so.6(+0x7c8c2)[0x7f73045148c2]
./a.out[0x403830]
./a.out[0x40326c]
./a.out[0x402a8b]
./a.out[0x402667]
./a.out[0x401707]
./a.out[0x40260a]
./a.out[0x4023ea]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f73044b9c05]
./a.out[0x401609]
======= Memory map: ========
00400000-00407000 r-xp 00000000 00:39 148951836                          /home/ugrads/r/reid_jordan8/CSCE221/PA5/Phase2/a.out
00606000-00607000 r--p 00006000 00:39 148951836                          /home/ugrads/r/reid_jordan8/CSCE221/PA5/Phase2/a.out
00607000-00608000 rw-p 00007000 00:39 148951836                          /home/ugrads/r/reid_jordan8/CSCE221/PA5/Phase2/a.out
01f54000-01f75000 rw-p 00000000 00:00 0                                  [heap]
7f7300000000-7f7300021000 rw-p 00000000 00:00 0
7f7300021000-7f7304000000 ---p 00000000 00:00 0
7f7304498000-7f7304650000 r-xp 00000000 fd:03 268570647                  /usr/lib64/libc-2.17.so
7f7304650000-7f7304850000 ---p 001b8000 fd:03 268570647                  /usr/lib64/libc-2.17.so
7f7304850000-7f7304854000 r--p 001b8000 fd:03 268570647                  /usr/lib64/libc-2.17.so
7f7304854000-7f7304856000 rw-p 001bc000 fd:03 268570647                  /usr/lib64/libc-2.17.so
7f7304856000-7f730485b000 rw-p 00000000 00:00 0
7f7304860000-7f7304875000 r-xp 00000000 fd:03 269333731                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f7304875000-7f7304a74000 ---p 00015000 fd:03 269333731                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f7304a74000-7f7304a75000 r--p 00014000 fd:03 269333731                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f7304a75000-7f7304a76000 rw-p 00015000 fd:03 269333731                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f7304a78000-7f7304b79000 r-xp 00000000 fd:03 269333747                  /usr/lib64/libm-2.17.so
7f7304b79000-7f7304d78000 ---p 00101000 fd:03 269333747                  /usr/lib64/libm-2.17.so
7f7304d78000-7f7304d79000 r--p 00100000 fd:03 269333747                  /usr/lib64/libm-2.17.so
7f7304d79000-7f7304d7a000 rw-p 00101000 fd:03 269333747                  /usr/lib64/libm-2.17.so
7f7304d80000-7f7304e69000 r-xp 00000000 fd:03 268438548                  /usr/lib64/libstdc++.so.6.0.19
7f7304e69000-7f7305069000 ---p 000e9000 fd:03 268438548                  /usr/lib64/libstdc++.so.6.0.19
7f7305069000-7f7305071000 r--p 000e9000 fd:03 268438548                  /usr/lib64/libstdc++.so.6.0.19
7f7305071000-7f7305073000 rw-p 000f1000 fd:03 268438548                  /usr/lib64/libstdc++.so.6.0.19
7f7305073000-7f7305088000 rw-p 00000000 00:00 0
7f7305088000-7f73050a9000 r-xp 00000000 fd:03 268437504                  /usr/lib64/ld-2.17.so
7f7305293000-7f7305298000 rw-p 00000000 00:00 0
7f73052a6000-7f73052a9000 rw-p 00000000 00:00 0
7f73052a9000-7f73052aa000 r--p 00021000 fd:03 268437504                  /usr/lib64/ld-2.17.so
7f73052aa000-7f73052ab000 rw-p 00022000 fd:03 268437504                  /usr/lib64/ld-2.17.so
7f73052ab000-7f73052ac000 rw-p 00000000 00:00 0
7ffd7df35000-7ffd7df56000 rw-p 00000000 00:00 0                          [stack]
7ffd7dfd8000-7ffd7dfda000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

1 个答案:

答案 0 :(得分:0)

我根据自己的问题找出了问题。

我删除了析构函数,错误语句消失了。

BinaryHeap::~BinaryHeap() //DONE
{   
while (!is_empty())
    v1.pop_back();
}

我不确定为什么,因为我得到的只是&#34;我不会调试你的程序&#34;这很好,但是如果你想知道这个错误发生的原因,你将不得不寻找其他地方,因为我没有回答为什么会发生这种情况。