C++ Динамическая память
Понимание того, как работает динамическая память в C++, необходимо для того, чтобы стать квалифицированным программистом C++. Память в программе на C++ делится на две части:
- Стек:Все переменные, объявленные внутри функции, будут занимать стековую память.
- Куча:Это память, не используемая программой, которая может применяться для динамического выделения памяти во время выполнения программы.
Часто невозможно заранее предсказать, сколько памяти потребуется для хранения конкретной информации в определённой переменной; требуемый размер памяти можно определить только во время выполнения.
В C++ можно использовать специальные операторы для выделения памяти в куче для переменных заданного типа во время выполнения, что возвращает адрес выделенного пространства. Эти операторы — этоnew-операторы.
Если динамически выделенное пространство памяти больше не нужно, можно использоватьdelete-оператор, чтобы удалить память, ранее выделенную оператором new.
Операторы new и delete
Ниже приведён общий синтаксис использования оператора new для динамического выделения памяти под любой тип данных:
new data-type;
Здесьdata-typeможет быть любым встроенным типом данных, включая массивы, или любым пользовательским типом данных, включая классы или структуры. Сначала рассмотрим встроенные типы данных. Например, мы можем определить указатель на тип double, затем запросить память, которая выделяется во время выполнения. Мы можем использовать следующую инструкцию:new-операторы, чтобы сделать это:
Если свободное хранилище исчерпано, выделение памяти может не удаться. Поэтому рекомендуется проверить, возвращает ли оператор new NULL-указатель, и предпринять соответствующие действия следующим образом:
malloc()Функция malloc() появилась в языке C и до сих пор существует в C++, но рекомендуется по возможности избегать использования malloc(). По сравнению с malloc(), главное преимущество new в том, что new не только выделяет память, но и создаёт объекты.
В любой момент, когда вы почувствуете, что переменная с динамически выделенной памятью больше не нужна, вы можете использовать оператор delete, чтобы освободить занимаемую ею память, как показано ниже:
delete pvalue; // 释放 pvalue 所指向的内存
В следующем примере используется вышеописанная концепция и демонстрируется, как использовать операторы new и delete:
Пример
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
Value of pvalue : 29495
Динамическое выделение памяти для массивов
Предположим, мы хотим выделить память для массива символов (строки из 20 символов). Мы можем использовать синтаксис из примера выше, чтобы динамически выделить память для массива, как показано ниже:
char* pvalue = NULL; // 初始化为 null 的指针 pvalue = new char[20]; // 为变量请求内存
Чтобы удалить только что созданный массив, используется следующая инструкция:
delete [] pvalue; // 删除 pvalue 所指向的数组
Ниже приведён общий синтаксис оператора new, который может выделять память для многомерных массивов, как показано ниже:
Одномерный массив
Двумерный массив
Тест экземпляра 2D-массива:
Пример
Трёхмерный массив
Тестовый экземпляр 3D-массива:
Пример
Динамическое выделение памяти для объектов
Объекты ничем не отличаются от простых типов данных. Например, посмотрите на следующий код; мы будем использовать массив объектов, чтобы пояснить эту концепцию:
Пример
Если вы хотите выделить память для массива, содержащего четыре объекта Box, конструктор будет вызван 4 раза; аналогично, когда эти объекты удаляются, деструктор также будет вызван столько же раз (4 раза).
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
Calling constructor! Calling constructor! Calling constructor! Calling constructor! Calling destructor! Calling destructor! Calling destructor! Calling destructor!Другие расширения