Что касается памяти, выделенной для переменных и массивов, то это статическая память, которая выделяется компилятором в зависимости от типа данных (в случае переменных) и размеров, предусмотренных для массивов.
Память, выделенная компилятором, размещается в стеке. Но в большинстве случаев мы можем не знать точного объема памяти, который нам нужен.
Что мы будем делать, так это выделять и освобождать столько памяти, сколько мы хотим. Это делается путем динамического выделения памяти.
Динамическое выделение памяти полезно, так как мы можем выделить память переменного размера, чего мы не можем достичь с памятью, выделенной компилятором. У нас есть возможность выделять память, когда она нам нужна, и освобождать ее, когда она нам не нужна.
Но помимо этих применений, мы также должны иметь в виду, что в случае с динамически выделяемой памятью ответственность за освобождение памяти лежит на пользователе. Если мы забудем освободить память, это вызовет утечку памяти, при которой память не будет освобождена до тех пор, пока программа не завершится.
Это может привести к тому, что будет использоваться слишком много памяти, что приведет к серьезным проблемам.
Динамическое выделение памяти
Язык C использует функции malloc, calloc и realloc для динамического выделения памяти. Чтобы отменить выделение памяти, динамически выделяемой этими функциями, C использует «свободный» вызов функции. Язык C++ также поддерживает эти функции языка C для выделения/освобождения памяти.
Помимо этих функций, C++ вводит два новых оператора, которые более эффективно управляют динамической памятью. Это оператор «new» для выделения памяти и оператор «delete» для отмены выделения памяти.
Оператор «new»
Оператор «new» выделяет память для переменной или любого другого объекта.
Общий синтаксис оператора «new»:
1 |
pointer_variable_of_data_type = new data type; |
Упомянутый выше тип данных может быть любым допустимым типом данных, поддерживаемым C++. Это может быть встроенный тип данных или любой определенный пользователем тип данных, включая классы и структуры.
Например,
1 2 |
int *ptr = NULL; ptr = new int(); |
В приведенном выше примере мы объявили переменную-указатель «ptr» на целое число и инициализировали ее значением null. Затем с помощью оператора «new» мы выделяем память для переменной «ptr». Если память доступна, второй оператор будет успешным. Если памяти нет, новый оператор выдает исключение «std::bad_alloc».
Следовательно, перед использованием этой переменной или объекта в программе лучше проверить, успешно ли выделена память оператором new.
Мы также можем инициализировать переменные с помощью оператора new следующим образом:
1 |
ptr = new int(10); |
В приведенном выше примере переменная-указатель «ptr» — это выделенная память с использованием оператора new, и в то же время присвоенное значение равно 10. Это еще один способ инициализации в C++.
Использование оператора new с массивами
Еще одно применение оператора «new» — выделение памяти для массивов. Здесь мы указываем количество элементов, которые должны быть выделены для массива.
Пример размещения элементов массива с использованием оператора «new» приведен ниже:
1 2 |
int* myarray = NULL; myarray = new int[10]; |
Здесь оператор new выделяет 10 непрерывных элементов типа integer переменной-указателю myarray и возвращает указатель на первый элемент myarray.
Оператор delete
Память, выделенная динамически с помощью оператора new, должна быть явно освобождена программистом. Для этого нам предоставляется оператор «delete».
Общий синтаксис оператора delete:
1 |
delete pointer_variable; |
Таким образом, мы можем освободить память, выделенную для переменной ptr, следующим образом:
1 |
delete ptr; |
Этот оператор освобождает память, выделенную для переменной «ptr», обратно в пул памяти.
Мы также можем использовать оператор delete, чтобы освободить память, выделенную для массивов.
Например, память, выделенная для массива myarray выше, может быть освобождена следующим образом:
1 |
delete[] myarray; |
Обратите внимание на оператор нижнего индекса, используемый с оператором delete. Это потому, что, поскольку мы выделили массив элементов, нам нужно освободить все местоположения.
Вместо этого, если бы мы использовали утверждение, вписываем:
1 |
delete myarray; |
Мы знаем, что myarray указывает на первый элемент массива, поэтому приведенный выше оператор удалит только первый элемент массива. Использование нижнего индекса «[]» указывает, что переменная, память которой освобождается, является массивом, и вся выделенная память должна быть освобождена.
В приведенном ниже примере программирования показано использование операторов new и delete в C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// Example program #include <iostream> #include <string> using namespace std; int main() { int *ptr = NULL; ptr = new int(); int *var = new int(12); if(!ptr) { cout<<"bad memory allocation"<<endl; } else { cout<<"memory allocated successfully"<<endl; *ptr = 10; cout<<"*ptr = "<<*ptr<<endl; cout<<"*var = "<<*var<<endl; } double *myarray = NULL; myarray = new double[10]; if(!myarray) {cout<<"memory not allocated"<<endl;} else { for(int i=0;i<10;i++) myarray[i] = i+1; cout<<"myarray values : "; for(int i=0;i<10;i++) cout<<myarray[i]<<"\t"; } delete ptr; delete var; delete[] myarray; return 0; |
Вывод данных:
1 2 3 4 |
memory allocated successfully *ptr = 10 *var = 12 myarray values : 1 2 3 4 5 6 7 8 9 10 |
Скриншот приведен ниже:
В приведенном выше примере кода мы продемонстрировали использование операторов new и delete. Мы использовали оператор «new» для выделения памяти для переменной, массивов, а также для инициализации другой переменной со значением. Затем мы удаляем эти объекты с помощью оператора «delete».
Итог
Вот и все, что мы хотели вам рассказать об операторах new и delete C++. Также мы можем использовать операторы new и delete для пользовательских типов данных, таких как классы и структуры. В следующей статье мы вам расскажем о библиотечных функциях в C++.
С Уважением, МониторБанк