为了清楚起见,这个错误来自学校作业的程序,但这个错误本身与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;
在临时分配带来的其他优势中,例如提高了空间局部性,这不需要程序员对delete
、h1
和h2
进行编程,而这是目前尚未完成的。
现在,如果你能原谅我的话,我必须找到我把剑落在哪里。