Выделение и освобождение памяти С++

Я пытаюсь реализовать класс массива, который может иметь динамический размер, и он будет выделять память без инициализации значений. Мой вопрос касается того, как я освобождаю память позже:

Могу ли я реализовать свой код таким образом?:

template<typename Type>
class Array {
    Type *values;

    Array(int size) : values(new (size * sizeof(Type)) char()) {}
    ~Array() {
        delete[] values;
    }
}

Или мне нужно что-то вроде этого?:

template<typename Type>
class Array {
    Type *values;
    void *memory;

    Array(int size) : memory(new (size * sizeof(Type)) char()), values(memory), size(size) {}
    ~Array() {
        delete[] memory;
    }
}

ПРИМЕЧАНИЕ!!!! Я знаю, что это будет выделять память без инициализации каких-либо объектов Type. Это предполагаемое поведение моего кода. Кроме того, приведенный выше код не является моей полной реализацией, это только код, который будет выделять и освобождать память, потому что это то, что меня интересует в этом вопросе.


После дальнейших исследований я обнаружил, что должен использовать malloc() и free(), чтобы делать то, что я пытаюсь сделать. Спасибо всем ответившим и комментирующим.


person Dynisious    schedule 17.02.2016    source источник
comment
Почему не memory(new Type[size])?   -  person Holt    schedule 17.02.2016
comment
FWIW, почему бы не vector<Type> или хотя бы изучить, как это работает и что делает! Во втором примере вы никогда не создаете Type, но уничтожаете size из них, что, безусловно, неверно. Кроме того, ваш синтаксис распределения выглядит странно, я бы ожидал new char[some size here].   -  person Ulrich Eckhardt    schedule 17.02.2016
comment
Причина, по которой я не использую память (новый тип[размер]) или вектор‹Тип›, заключается в том, что оба экземпляра будут выделять память, а затем создавать экземпляр для каждой позиции. В своем вопросе я указал, что не хочу создавать экземпляры типа, а только выделяю для него память.   -  person Dynisious    schedule 17.02.2016
comment
@Dynisious Я бы порекомендовал вам изучить разницу между new char[42] и new char[42]().   -  person Fiktik    schedule 17.02.2016


Ответы (2)


Вы можете использовать Type*, чтобы упростить жизнь, и использовать operator new, чтобы получить память без создания объектов.

Type* values; //No aliasing/casting issues
Array(int size) : values((Type*)::operator new(sizeof(Type) * size)) //...
~Array() { /*clean up extant objects*/ ::operator delete(values); }

Затем вы можете использовать размещение new и явные вызовы деструктора для управления элементами. Кроме того, размещение new не выделяет память. Он создает объект по указанному адресу.

person Weak to Enuma Elish    schedule 17.02.2016

Размещение new на самом деле не выделяет никакой памяти. Это просто синтаксис для вызова конструктора с уже выделенной памятью.

В вашем деструкторе вы должны вручную вызывать деструкторы для каждого существующего элемента, а затем освобождать память так же, как она была выделена. Будьте очень осторожны с исключениями.

Вероятно, вам следует использовать std::allocator<T>::allocate и std::allocator<T>::deallocate, но вы можете использовать malloc/free, new char[]/delete[] (char*)arr или ::operator new/::operator delete.

person o11c    schedule 17.02.2016
comment
Не включено в мой ответ: class-scope operator new и operator delete, так как я их не понимаю. - person o11c; 17.02.2016