使用一个类的两个单独实例时,Malloc错误2372

时间:2015-12-08 23:19:42

标签: c++ class malloc

为了清楚起见,这个错误来自学校作业的程序,但错误本身与malloc的问题有关,而不是理解作业。在作业中我只使用了这个类的一个实例,所以这个问题主要是为了将来参考。当我使用在此声明的Heap类的2个不同实例时,我遇到的问题出现了:

a4.h

    #include <iostream>

    using namespace std; 

    /*
            Class Declarations
    ********************************************************************
    */

    // A Heap implemented with a growing array

    class Heap{

    public:
        Heap(); 
        ~Heap(); 
        void insert ( int item ); 
        int remove(); 
        void printheap(); 

    private:
        void trickleup   ( int pos ); 
        void trickledown ( int pos ); 
        void swap    ( int pos1 , int pos2 ); 

        int* A; 
        int size; 
        int capacity; 
    }; 




    /*
            Class Methods
    *********************************************************************
    */

    // For Heap

    Heap::Heap(){
        A = NULL; 
        size = 0; 
        capacity = 0; 
    }

    Heap::~Heap(){

        delete A; 
    }

    void Heap::insert ( int item ){

        if ( size == capacity ){
            int* newpointer = new int[(capacity*2)+1]; 
            for (int i = 0; i < size; i++) newpointer[i] = A[i]; 
            delete A; 
            A = newpointer; 
        }

        A[size] = item; 
        size += 1; 
        trickleup (size-1); 
        return; 
    }

    int Heap::remove(){

        size -= 1; 
        int temp = A[0]; 
        swap ( 0 , size ); 
        trickledown (0); 
        return temp; 
    }

    void Heap::printheap(){

        cout << "Root -> [ "; 
        for (int i = 0; i <  size; i++) cout << A[i] << " "; 
        cout << "]\n"; 
        return; 
    }

    void Heap::trickleup ( int pos ){

        int p0 = pos; 
        int p1 = (pos-1)/2; 

        if ( p0 == 0 ){
            trickledown (0); 
            return; 
        }
        if ( A[p0] > A[p1] ){
            swap ( p0 , p1 ); 
            trickleup ( p1 ); 
        }
        else trickledown (p0); 
        return; 
    }

    void Heap::trickledown ( int pos ){

        int p0 = pos; 
        int p1 = (2*pos)+1; 
        int p2 = (2*pos)+2; 

        if ( p1 >= size ) return; 
        if ( p2 >= size ){
            if ( A[p0] < A[p1] ) swap ( p0 , p1 ); 
            return; 
        }

        bool f1 = ( A[p0] < A[p1] );    
        bool f2 = ( A[p0] < A[p2] );    

        if ( (A[p1] >= A[p2]) && f1 ){
            swap ( p0 , p1 ); 
            trickledown ( p1 ); 
        }
        else if ( (A[p1] < A[p2]) && f2 ){
            swap ( p0 , p2 ); 
            trickledown ( p2 ); 
        }
        return; 
    }

    void Heap::swap ( int pos1 , int pos2 ){

        int temp = A[pos1]; 
        A[pos1] = A[pos2]; 
        A[pos2] = temp; 
        return; 
    }

我使用new来请求内存的唯一时间是插入函数。

当我运行从 htest.cpp 编译的测试程序并运行h1测试和h2测试的两个部分时,会出现问题。如果我只运行两个测试中的一个,则问题不会发生。这是测试程序:

htest.cpp

    #include <cstdlib>
    #include <iostream> 
    #include "a4.h"

    using namespace std; 

    int main(){

        cout << "\nCreating h1 And h2\n\n"; 

        Heap* h1 = new Heap(); 
        Heap* h2 = new Heap(); 

        cout << "\nAdding 0-6 To h1\n\n"; 

        h1->insert ( 0 ); cout << "h1: "; h1->printheap(); 
        h1->insert ( 1 ); cout << "h1: "; h1->printheap(); 
        h1->insert ( 2 ); cout << "h1: "; h1->printheap(); 
        h1->insert ( 3 ); cout << "h1: "; h1->printheap(); 
        h1->insert ( 4 ); cout << "h1: "; h1->printheap(); 
        h1->insert ( 5 ); cout << "h1: "; h1->printheap(); 
        h1->insert ( 6 ); cout << "h1: "; h1->printheap(); 

        cout << "\nRemoving All Elements From h1\n\n"; 

        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 
        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 
        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 
        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 
        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 
        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 
        cout << "Removed: " << h1->remove(); 
        cout << "  h1: "; h1->printheap(); 

        cout << "\nAdding 6-0 To h2\n\n"; 

        h2->insert ( 6 ); cout << "h2: "; h2->printheap(); 
        h2->insert ( 5 ); cout << "h2: "; h2->printheap(); 
        h2->insert ( 4 ); cout << "h2: "; h2->printheap(); 
        h2->insert ( 3 ); cout << "h2: "; h2->printheap(); 
        h2->insert ( 2 ); cout << "h2: "; h2->printheap(); 
        h2->insert ( 1 ); cout << "h2: "; h2->printheap(); 
        h2->insert ( 0 ); cout << "h2: "; h2->printheap(); 

        cout << "\nRemoving All Elements From h2\n\n"; 

        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 
        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 
        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 
        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 
        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 
        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 
        cout << "Removed: " << h2->remove(); 
        cout << "  h2: "; h2->printheap(); 

        cout << "\n"; 

        return 0; 
    }

编译完程序并运行它(使用GNU C ++编译器)后,得到以下输出:

输出

    Creating h1 And h2


    Adding 0-6 To h1

    h1: Root -> [ 0 ]
    h1: Root -> [ 1 0 ]
    h1: Root -> [ 2 0 1 ]
    h1: Root -> [ 3 2 1 0 ]
    h1: Root -> [ 4 3 1 0 2 ]
    h1: Root -> [ 5 3 4 0 2 1 ]
    h1: Root -> [ 6 3 5 0 2 1 4 ]

    Removing All Elements From h1

    Removed: 6  h1: Root -> [ 5 3 4 0 2 1 ]
    Removed: 5  h1: Root -> [ 4 3 1 0 2 ]
    Removed: 4  h1: Root -> [ 3 2 1 0 ]
    Removed: 3  h1: Root -> [ 2 0 1 ]
    Removed: 2  h1: Root -> [ 1 0 ]
    Removed: 1  h1: Root -> [ 0 ]
    Removed: 0  h1: Root -> [ ]

    Adding 6-0 To h2

    htest: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
    Aborted (core dumped)

我想知道为什么会出现这个错误,因为它似乎没有做任何非法请求内存的事情。如果有人可以尝试清楚解释问题,我会非常感激,因为我只有大约一年的C ++经验。

*编辑:更改析构函数以不删除大小和容量,并在重新调整数组大小之前向insert函数添加了删除A行。

1 个答案:

答案 0 :(得分:1)

很遗憾我之前没有发现过这个。回答之后,我会把自己扔到剑上。

Heap::insert从未设置capacity。它保持为0,因此在第一个之后插入不会触发if (size == capacity)并且不会调整A的大小。结果,A超出了边界并破坏了堆(内存堆,而不是类Heap)。

我推荐一个小编辑:

void Heap::insert(int item)
{
    if (size == capacity)
    {
        capacity = (capacity * 2) + 1; // Note: many tests have shown that 1.5 is a 
                                       // better expansion factor than 2.
        int* newpointer = new int[capacity];
        for (int i = 0; i < size; i++)
            newpointer[i] = A[i];
        delete A;
        A = newpointer;
    }

    A[size] = item;
    size += 1;
    trickleup(size - 1);
    return;
}

另外

Heap* h1 = new Heap();
Heap* h2 = new Heap();

不需要动态分配,可以定义为

Heap h1;
Heap h2;

临时分配带来的其他优势,例如改进的空间局部性,这不需要程序员delete h1h2,这是目前尚未完成的事情。

现在,如果你能原谅我,我必须找到我离开剑的地方。