Обычно, объем памяти, необходимый для той или иной переменной, задается еще до процесса компиляции посредством объявления этой переменной. Если же возникает необходимость в создание переменной, размер которой неизвестен заранее, то используют динамическую память. Резервирование и освобождение памяти в программах на C++ может происходить в любой момент времени. Осуществляются операции распределения памяти двумя способами:
- с помощью функции malloc, calloc, realloc и free;
- посредством оператора new и delete.
Функция malloc резервирует непрерывный блок ячеек памяти для хранения указанного объекта и возвращает указатель на первую ячейку этого блока. Обращение к функции имеет вид:
void *malloc(size);
Здесь size — целое беззнаковое значение, определяющее размер выделяемого участка памяти в байтах. Если резервирование памяти прошло успешно, то функция возвращает переменную типа void *, которую можно привести к любому необходимому типу указателя.
Функция — calloc также предназначена для выделения памяти. Запись ниже означает, что будет выделено num элементов по size байт.
void *calloc (nime, size);
Эта функция возвращает указатель на выделенный участок или NULL при невозможности выделить память. Особенностью функции является обнуление всех выделенных элементов.
Функция realloc изменяет размер выделенной ранее памяти. Обращаются к ней так:
char *realloc (void *p, size);
Здесь p — указатель на область памяти, размер которой нужно изменить на size. Если в результате работы функции меняется адрес области памяти, то новый адрес вернется в качестве результата. Если фактическое значение первого параметра NULL, то функция realloc работает также, как и функция malloc, то есть выделяет участок памяти размером size байт.
Для освобождения выделенной памяти используется функция free. Обращаются к ней так:
void free (void *p size);
Здесь p — указатель на участок памяти, ранее выделенный функциями malloc, calloc или realloc.
Операторы new и delete аналогичны функциям malloc и free. New выделяет память, а его единственный аргумент — это выражение, определяющее количество байтов, которые будут зарезервированы. Возвращает оператор указатель на начало выделенного блока памяти. Оператор delete освобождает память, его аргумент — адрес первой ячейки блока, который необходимо освободить.
Динамический массив — массив переменной длины, память под который выделяется в процессе выполнения программы. Выделение памяти осуществляется функциями calloc, malloc или оператором new. Адрес первого элемента выделенного участка памяти хранится в переменной, объявленной как указатель. Например, следующий оператор означает, что описан указатель mas и ему присвоен адрес начала непрерывной области динамической памяти, выделенной с помощью оператора new:
int *mas=new int[10];
Выделено столько памяти, сколько необходимо для хранения 10 величин типа int.
Фактически, в переменной mas хранится адрес нулевого элемента динамического массива. Следовательно, адрес следующего, первого элемента, в выделенном участке памяти — mas+1, а mas+i является адресом i-го элемента. Обращение к i-му элементу динамического массива можно выполнить, как обычно mas[i], или другим способом *(mas +i). Важно следить за тем, чтобы не выйти за границы выделенного участка памяти.
Когда динамический массив (в любой момент работы программы) перестает быть нужным, то память можно освободить с помощью функции free или оператора delete.
Предлагаю рассмотреть несколько задач, закрепляющих данный урок:
Задача 1
Найти сумму вещественных элементов динамического массива.
//Пример использования функции malloc и free #include "stdafx.h" #include <iostream> using namespace std; int main() { setlocale(LC_ALL,"Rus"); int i, n; float *a; //указатель на float float s; cout<<"\n"; cin>>n; //ввод размерности массива //выделение памяти под массив из n вещественных элементов a=(float *)malloc(n*sizeof(float)); cout<<"Введите массив A \n"; //ввод элементов массива for (i=0; i<n; i++) { cin>>*(a+i); } //накапливание суммы элементов массива for (s=0, i=0; i<n; i++) s+=*(a+i); //вывод значения суммы cout<<"S="<<s<<"\n"; //освобождение памяти free(a); system("pause"); return 0; }
Задача 2
Изменить динамический массив целых чисел таким образом, чтобы его положительные элементы стали отрицательными и наоборот. Для решения задачи мы будем умножать каждый элемент на -1.
//Пример использования операторов new и delete #include "stdafx.h" #include <iostream> using namespace std; int main() { setlocale(LC_ALL,"Rus"); int i, n; //ввод количества элементов массива cout<<"n="; cin>>n; //выделение памяти int *a=new int[n]; cout<<"Введите элементы массива:\n"; //ввод массива for (i=0; i<n; i++) cin>>a[i]; //вывод заданного массива for (i=0; i<n; i++) cout<<a[i]<<"\t"<<"\n"; //преобразование массива for (i=0; i<n; i++) a[i]=-a[i]; //вывод преобразованного массива for (i=0; i<n; i++) cout<<a[i]<<"\t"; cout<<"\n"; //освобождение памяти delete []a; system("pause"); return 0; }