Маллок в конструкторах - PullRequest
5 голосов
/ 10 июня 2011

Я реализую класс двоичной кучи.Куча реализована в виде массива, который выделяется динамически.Класс heap имеет члены, емкость, размер и указатель на массив, как:

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

Так как я неправильно использую дважды и разыменую обауказатели в конструкторе, я должен проверить, удастся ли это.Но что мне делать, если это не удается?Сам конструктор не может ничего возвратить, чтобы указать, что это не удалось.Это хорошая практика программирования, чтобы вообще избегать mallocs в конструкторах?

Ответы [ 3 ]

14 голосов
/ 10 июня 2011

Прежде всего, вам не нужна переменная-член Heap* внутри вашего 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 для его освобождения, а не free. ( Исправление : в приведенном выше примере вы используете новую форму массива, new[], поэтому вы должны вызывать форму удаления массива, delete[]).

Наконец, вы не показали, как объявляется ElementType, но если это тип, который имеет конструктор / деструктор не по умолчанию (или если это параметр шаблона, который означает, что он потенциально может быть таким типом), вы имеет для использования new вместо malloc при его выделении, потому что malloc не вызовет конструктор (а free не вызовет деструктор). Как правило, рекомендуется всегда использовать new и delete в C ++, а не malloc и free.

5 голосов
/ 10 июня 2011

Вы должны изучить некоторые базовые «правила дорожного движения» C ++, первое из которых:

Используйте стандартную библиотеку шаблонов!твой конструктор?Вам не нужен один.

Как правило, любое использование malloc() или free() в C ++ является «запахом кода».Это верный способ получить неправильно построенные объекты, переполнения буфера и утечки памяти.Используйте new и delete, желательно с умными указателями.

Или, еще лучше.просто по возможности создавайте свои объекты статически.

1 голос
/ 10 июня 2011

Вы размещаете объект в своем собственном конструкторе?Не имеет смысла:

    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 выдаст исключение при ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...