Динамическое управление памятью — это процесс выделения и освобождения блоков памяти во время выполнения. Это критический аспект программирования на 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; }
Эти новые операторы обеспечивают простой в использовании интерфейс и дают следующие преимущества:
- Нет необходимости указывать размер памяти; Неявно определяется типом данных.
- Нет необходимости в явном приведении типа указателя.
- Выделение памяти и инициализация могут быть выполнены за один шаг.
Чтобы выделить динамическую память для массива, 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: Знаете ли вы, что происходит, когда вы долго удерживаете кнопку хлопка на среднем уровне?