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

Malloc Error 2372 When Using Two Seperate Instances Of One Class

本文关键字:实例 Malloc 2372 单独 错误 一个 两个      更新时间:2023-10-16

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

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 h2nn"; 
        Heap* h1 = new Heap(); 
        Heap* h2 = new Heap(); 
        cout << "nAdding 0-6 To h1nn"; 
        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 h1nn"; 
        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 h2nn"; 
        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 h2nn"; 
        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; 
    }

在编译并运行这个程序(使用GNUC++编译器)后,我得到以下输出:

输出

    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++经验。

*编辑:将析构函数更改为不删除大小和容量,并在重新调整数组大小之前向插入函数添加了一行delete a。

很遗憾我以前没有发现这个。回答后我会跳到剑上。

CCD_ 2从不设置CCD_ 3。它保持为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;

在临时分配带来的其他优势中,例如提高了空间局部性,这不需要程序员对deleteh1h2进行编程,而这是目前尚未完成的。

现在,如果你能原谅我的话,我必须找到我把剑落在哪里。