#c #memory-management #new-operator
#c #управление памятью #new-оператор
Вопрос:
Почти общеизвестно, что приведенный ниже код корректно освобождает память от 100 целых чисел.
int* ip = new int[100];
delete [] ip;
И я думаю, что даже для пользовательских классов это работает:
Node* ip = new Node[100];
delete [] ip;
-
В первом случае определяется ли размер освобождаемой памяти (400 байт) во время компиляции? В принципе, что происходит внутри?
-
Во втором случае будет ли вызываться деструктор
Node
для каждого из 100 объектов?
По сути, я использовал этот синтаксис, но никогда не понимал, что происходит внутри, и теперь мне любопытно.
Комментарии:
1. Однако используйте
std::vector<>
в обычном режиме.
Ответ №1:
- Нет. Распределитель памяти незаметно отслеживает размер. Размер не может быть определен во время компиляции, потому что тогда распределение не было бы действительно динамичным и следующее не работало бы:
size_t n;
std::cin >> n;
a = new int[n];
// do something interesting
delete[] a;
- ДА. Чтобы убедиться в этом факте, попробуйте
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
anddelete[]
обычно компилируются в вызовы функций, которые обертываютmalloc
andfree
или интерфейс уровня операционной системы. Деструктор также вызывается распределителем памяти (в конце концов, это просто функция).3. Ну ладно. Теперь это имеет смысл. Удивительно, как долго я использовал синтаксис, предполагая, что он волшебным образом работает, не задумываясь об этом.
4. Итак, если я динамически отменяю выделение массива из ‘N’ объектов класса, внутри функции выделения библиотеки деструктор будет вызываться для каждого объекта … звучит нормально 🙂
5. Я бы сказал, что деструкторы с большей вероятностью вызываются кодом, введенным компилятором, а не распределителем памяти как частью библиотеки языковой поддержки.