我正在实现二进制堆类。堆实现为动态分配的数组。堆类具有成员容量,大小和指向数组的指针,如:
class Heap
{
private:
Heap* H;
int capacity; //Size of the array.
int size; //Number of elements currently in the array
ElementType* Elements; //Pointer to the array of size (capacity+1)
//I've omitted the rest of the class.
};
我的建筑看起来像这样:
Heap::Heap (int maxElements)
{
H = ( Heap* ) malloc ( sizeof ( Heap ) );
H -> Elements = ( ElementType* ) malloc ( ( maxElements+1 )*sizeof ( ElementType ) );
H -> Elements[0] = DUMMY_VALUE; //Dummy value
H -> capacity = maxElements;
H -> size = 0;
}
由于我在两次mallocing并在构造函数中解除引用两个指针,我应该检查它是否成功。但如果它失败了我该怎么办?构造函数本身不能返回任何内容以指示它失败。完全避免构造函数中的mallocs是一种很好的编程习惯吗?
答案 0 :(得分:14)
首先,你在<{1}}对象中不需要一个Heap*
成员变量,你肯定不应该在{{1}中为它分配内存构造函数 - 这只是在寻找麻烦。您也不应该以{{1}}的身份访问您的成员变量,而只是Heap
。
您需要分配的唯一内容是Heap
数组。
关于处理分配失败,构造函数应该通过异常指示失败。甚至还有一个标准的异常类型H->Elements
,它通常用于表示无法分配内存。
例如:
Elements
更好的是,使用Elements
而不是std::bad_alloc
来分配内存。如果#include <stdexcept> // for std::bad_alloc
...
Heap::Heap (int maxElements)
{
Elements = ( ElementType* ) malloc ( ( maxElements+1 )*sizeof ( ElementType ) );
if (Elements == NULL)
throw std::bad_alloc("Failed to allocate memory");
...
}
无法分配内存,new
将自动抛出类型malloc
的异常。
示例:
new
注意:如果您使用std::bad_alloc
分配对象,则必须使用Heap::Heap (int maxElements)
{
Elements = new ElementType[maxElements + 1]; // throws std::bad_alloc on failure
...
}
来释放它,而不是new
。 (更正:在上面的示例中,您使用的是新的数组形式delete
,因此您应该调用delete的数组形式free
)。
最后,您还没有展示如何声明new[]
,但是如果它是一个具有非默认构造函数/析构函数的类型(或者它是一个模板参数,这意味着它可能是这样的类型) , 在分配时使用delete[]
而不是ElementType
,因为new
不会调用构造函数(并且malloc
不会调用析构函数)。一般来说,最好始终在C ++中使用malloc
和free
,而不是new
和delete
。
答案 1 :(得分:5)
你应该学习一些基本的C ++“道路规则”,第一个是:
使用标准模板库!
class Heap {
private:
std::vector<ElementType> elements;
}
你的构造函数?你不需要一个。
通常,在C ++中使用malloc()
或free()
是一种“代码味道”。这是一种肯定的方式,可以最终导致错误构造的对象,缓冲区溢出和内存泄漏。使用new
和delete
,最好使用智能指针。
或者,更好。尽可能静态地构建对象。
答案 2 :(得分:1)
您是在自己的构造函数中分配对象吗?没有意义:
H = ( Heap* ) malloc ( sizeof ( Heap ) );
构造函数由内存分配后的new
运算符调用。如果您正在尝试创建单例 - 使用将实例化对象的静态方法,并调用
class Heap{
public:
static Heap* Get();
private:
Heap();
static Heap* H;
}
Heap *Heap::H = 0;
Heap * Heap::Get()
{
if (!H)
H = new (Heap);
return H;
}
Heap::Heap()
{
// whatever else
}
对于您的问题:malloc
是一个C函数。在C ++中 - 使用new
。您不需要检查返回值,new
将在失败时抛出异常。