开发者

Malloc in constructors

I'm implementing a binary heap class. The heap is implemented as an array that is dynamically allocated. The heap class has members capacity, size and a pointer to an array, as:

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.
};

My construcor looks like this:

Heap::Heap (int maxElements)
{
    H = ( Heap* ) malloc ( sizeof ( Heap ) );
    H -> Elements = ( ElementType* ) malloc ( ( maxElements+1 )*sizeof ( ElementType ) );
    H -> Elements[0] = DUMMY_VALUE; //Dummy val开发者_JAVA技巧ue
    H -> capacity = maxElements;
    H -> size = 0;  
}

Since I'm mallocing twice and dereferencing both pointers in the constructor, I should check whether it succeeds. But what should I do if it fails? The constructor can't itself return anything to indicate that it failed. Is it good programming practice to avoid mallocs in constructors altogether?


First of all, you do not need a Heap* member variable inside your Heap object, and you certainly should not be allocating memory for it in the Heap constructor - that's just asking for trouble. Nor should you be accessing your member variables as H->Elements, but rather simply as Elements.

The only thing you need to allocate is the Elements array.

With regards to handling allocation failures, constructors should indicate failures via an exception. There is even a standard exception type, std::bad_alloc that is usually used to indicate a failure to allocate memory.

For example:

#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");
    ...
}

Even better, use new rather than malloc to allocate the memory. new will automatically throw an exception of type std::bad_alloc if it fails to allocate memory.

Example:

Heap::Heap (int maxElements) 
{
    Elements = new ElementType[maxElements + 1];  // throws std::bad_alloc on failure
    ...
}

Note: if you use new to allocate the object, you must use delete to free it rather than free. (Correction: In the example above, you are using the array form of new, new[], so you should call the array form of delete, delete[]).

Finally, you haven't shown how ElementType is declared, but if it's a type that has a non-default constructor/destructor (or if it's a template parameter which means it can potentially be such a type), you have to use new rather than malloc when allocating it because malloc will not call the constructor (and free will not call the destructor). In general, it's good practice to just always use new and delete in C++ rather than malloc and free.


You should learn some basic C++ 'rules of the road', the first of which is:

Use the Standard Template Library!

class Heap {
  private: 
    std::vector<ElementType> elements;
}

And your constructor? You don't need one.

In general, any use of malloc() or free() in C++ is a 'code smell'. It's a sure-fire way of ending up with incorrectly constructed objects, buffer overflows, and memory leaks. Use new and delete, preferably with smart pointers.

Or, better yet. just have your objects constructed statically whenever possible.


You're allocating the object in its own constructor? Doesn't make sense:

    H = ( Heap* ) malloc ( sizeof ( Heap ) );

Constructor is called by the new operator, right after the memory allocation. If you're trying to create a singleton - use a static method which will instantiate the object, and call

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
}

To your question: malloc is a C function. In C++ - use new. You don't need to check for return values then, new will throw exception on failure.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜