Удаление массива объектов класса?

#c #memory-management #new-operator

#c #управление памятью #new-оператор

Вопрос:

Почти общеизвестно, что приведенный ниже код корректно освобождает память от 100 целых чисел.

 int* ip = new int[100];
delete [] ip; 
  

И я думаю, что даже для пользовательских классов это работает:

 Node* ip = new Node[100];
delete [] ip; 
  
  1. В первом случае определяется ли размер освобождаемой памяти (400 байт) во время компиляции? В принципе, что происходит внутри?

  2. Во втором случае будет ли вызываться деструктор Node для каждого из 100 объектов?

По сути, я использовал этот синтаксис, но никогда не понимал, что происходит внутри, и теперь мне любопытно.

Комментарии:

1. Однако используйте std::vector<> в обычном режиме.

Ответ №1:

  1. Нет. Распределитель памяти незаметно отслеживает размер. Размер не может быть определен во время компиляции, потому что тогда распределение не было бы действительно динамичным и следующее не работало бы:
 size_t n;
std::cin >> n;
a = new int[n];
// do something interesting
delete[] a;
  
  1. ДА. Чтобы убедиться в этом факте, попробуйте
 struct Foo {
    ~Foo() { std::cout << "Goodbye, cruel world.n"; }
};

// in main
size_t n;
std::cin >> n;
Foo *a = new Foo[n];
delete[] a;
  

Комментарии:

1. Итак, является ли распределитель памяти отдельным процессом / потоком / модулем в любой скомпилированной программе на C ? И кто выполняет работу по вызову деструктора в случае B? Это «распределитель памяти» или в скомпилированном коде есть инструкции для вызова деструктора? Спасибо!

2. Распределитель памяти является частью стандартной библиотеки C . инструкции new and delete[] обычно компилируются в вызовы функций, которые обертывают malloc and free или интерфейс уровня операционной системы. Деструктор также вызывается распределителем памяти (в конце концов, это просто функция).

3. Ну ладно. Теперь это имеет смысл. Удивительно, как долго я использовал синтаксис, предполагая, что он волшебным образом работает, не задумываясь об этом.

4. Итак, если я динамически отменяю выделение массива из ‘N’ объектов класса, внутри функции выделения библиотеки деструктор будет вызываться для каждого объекта … звучит нормально 🙂

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