Сколько раз new [] и delete [] совершают вызовы для выделения и освобождения памяти? - PullRequest
0 голосов
/ 28 сентября 2018

В C++, каждый раз, когда используется new [] или delete [], сколько раз каждый выделяет или освобождает память?Мой вопрос более специфичен для использования их в классах с их соответствующими конструкторами и деструктором.

Например, возьмем следующий класс:

#include <iostream>

class Cell
{
public:
    Cell() : _value(2)
    {
        std::cout << "Cell being made!\n";
    }
    ~Cell()
    {
        std::cout << "Cell being freed!\n";
    }

    const int& getVal() const
    {
        return _value;
    }
private:
    int _value;
};

Теперь, скажем, массив этого типа классанеобходимо, и используется new[], как показано ниже

Cell* cells = new Cell[5];

Когда это выполняется в исполняемом файле или программе, я также вижу следующее, напечатанное на стандартный вывод:

Cell being made!
Cell being made!
Cell being made!
Cell being made!
Cell being made!

И впоследствиикогда delete[] вызывается для указателя cells, я вижу:

Cell being freed!
Cell being freed!
Cell being freed!
Cell being freed!
Cell being freed!

Мой вопрос в том, что при каждом вызове конструктора размер памяти равен одному выделяемому экземпляру класса?Например, new Cell[5] выделяет память 5 раз?Или он выделяет один раз, а затем делает 5 вызовов для конструктора как просто вызов функции?То же самое с delete[], освобождает ли он при каждом вызове деструктора?

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

Вы смешиваете две разные концепции:

  1. Распределение / освобождение памяти
  2. Строительство / разрушение объекта

new и delete doи для нас.

new Cell[5];

Общий объем памяти, необходимый для всех 5 объектов, выделяется в одной операции выделения памяти.Это не может быть 5 распределений, так как 5 различных распределений не могут гарантировать последовательные пробелы.

После выделения памяти для 5 объектов new должен инициализировать 5 объектов с помощью вызова конструктора по умолчанию.Здесь у нас есть 5 отдельных вызовов конструктора.

Подобные вещи происходят во время delete [] cells.Он должен уничтожить 5 объектов, вызвав деструктор из 5 различных объектов.Затем вся выделенная память освобождается за одну операцию освобождения.

0 голосов
/ 28 сентября 2018

Инструкция Cell* cells = new Cell[5]; означает, что вы создаете 5 объектов Cell, лежащих последовательно в области Heap (основной памяти).cells - это указатель на область стека (основной памяти), который указывает на объекты (cells будет просто хранить адрес первого объекта).После этого каждый объект будет вызывать конструктор по умолчанию, чтобы инициировать его значение, поэтому вы увидите 5 строк Cell being made!.

Когда вы не хотите использовать объекты и хотите освободить их из памяти кучи, вы должны использовать delete [] cells инструкция.Затем 5 объектов, на которые указывает cells, будут вызывать 5 деструкторов, чтобы сделать что-то, прежде чем объекты будут удалены из памяти, но cells все еще существует в памяти стека и может использоваться для указания на другой объект Cell (cellsбудет удален из области только тогда, когда cells выйдет из области видимости, теперь удаляются только 5 объектов в куче памяти).Таким образом, вы можете увидеть 5 строк Cell being freed!

0 голосов
/ 28 сентября 2018

Если a (ключевое слово в отличие от оператора) new [] преуспевает, он выделяет один блок, достаточно большой, чтобы вместить все объекты, после чего объекты затем объединяются в этот блок.Аналогично, (ключевое слово) delete [] вызовет деструктор для каждого объекта в массиве, а затем освободит весь блок.

Операторы new и delete (и new [] и delete []) выполняют фактическое распределение/ deallocation и будет вызываться один раз для любого использования ключевых слов new / new [] и delete / delete [].

...