Динамическое управление памятью — это процесс выделения и освобождения блоков памяти во время выполнения. Это критический аспект программирования на C и C++, где выделение памяти выполняется динамически.

В этой статье мы подробно рассмотрим динамическое управление памятью в языках на основе C и исследуем различия между динамическим выделением и освобождением памяти в C и C++.

Понимание памяти

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

текстовый сегмент (также известный как сегмент кода) содержит скомпилированный код программы. Это машинное представление шагов программы, которые должны быть выполнены, включая все пользовательские и системные функции.

Сегмент данных далее подразделяется на два сегмента: Инициализированные и Неинициализированные. Все глобальные, постоянные и статические данные хранятся в сегменте инициализированных данных. Все неинициализированные данные хранятся в сегменте неинициализированных данных.

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

стек используется для хранения ваших локальных переменных и для отправки аргументов функциям, а также адреса возврата инструкции, которая должна быть выполнена после завершения вызова функции. Когда требуется новый кадр стека (из-за только что вызванной функции), стек растет вниз.

Динамическое управление памятью

Любая память, выделенная во время выполнения, обслуживается из сегмента Heap памяти. И C, и C++ поддерживают выделение памяти из кучи, но для этого используют совершенно разные наборы функций.

Давайте взглянем на функции C для динамического управления памятью.

Функции управления памятью в C

Следующие четыре функции составляют основу управления памятью в C.

  • malloc(): выделяет один блок запрошенной памяти.
  • calloc(): выделяет несколько блоков запрошенной памяти.
  • realloc(): перераспределяет память, занимаемую функциями malloc() или calloc().
  • free(): освобождает динамически выделенную память.

Ниже приведен пример использования функции malloc и free.

#include <stdio.h>
#include <stdlib.h>

int main() {
  int *p = (int*) malloc(sizeof(int));
  *p = 5;
  printf("%d\n", *p);
  free(p);
}

Обратите внимание, что все эти четыре функции по-прежнему доступны в C++, и пользователи могут использовать их для управления памятью так же, как в C.

Операторы управления памятью в C++

C++ представил новые способы управления динамической памятью. Два новых оператора, называемые new и delete, были добавлены в C++ для выполнения задач, связанных с управлением динамической памятью.

Вот аналогичная программа на C++, написанная с использованием этих новых операторов.

#include <iostream>

int main() {
  int *p = new int(5);
  cout << p << endl;
  delete p;
}

Эти новые операторы обеспечивают простой в использовании интерфейс и дают следующие преимущества:

  1. Нет необходимости указывать размер памяти; Неявно определяется типом данных.
  2. Нет необходимости в явном приведении типа указателя.
  3. Выделение памяти и инициализация могут быть выполнены за один шаг.

Чтобы выделить динамическую память для массива, C++ представил два новых оператора new[] и delete[]. Вот как их использовать —

#include <iostream>

int main() {
  int *p = new int[3];
  p[0] = 0; p[1] = 10; p[2] = 100;
  delete[] p;
}

Обратите внимание, что операторы new[] и delete[] отличаются от операторов new и delete.

Функции управления памятью в C++

Обратите внимание на тонкую разницу в заголовках этого и предыдущего разделов.

Помимо операторов new и delete, в C++ представлены две новые функции для динамического управления памятью. Это «оператор new()» и «оператор delete()». Не путайте их с оператором new и оператором delete. Вот как они используются.

#include <iostream>

int main() {
  int *p = (int*) operator new(sizeof(int));
  cout << p << endl;
  operator delete(p);
}

Если вы все еще в замешательстве, я бы порекомендовал пройти эту тред SO.

На этом мы подошли к концу еще одного блога по C++. Не стесняйтесь оставлять свои сомнения в разделе комментариев. Если вы хотите прочитать больше таких интересных блогов по C++, обратитесь к моей серии статей in C++ здесь.

PS: Знаете ли вы, что происходит, когда вы долго удерживаете кнопку хлопка на среднем уровне?