Операторы свободной памяти new и delete
Вы уже имеете опыт написания программ и, наверняка, попадали в ситуации, когда необходимо было решить вопросы подобные следующим:
- Как динамически выделять память под массив? Т.е., чтобы пользователь задавал сам размерность массива или программист мог в нужный момент изменить размерность массива.
- Как динамически создавать и уничтожать переменные? Т.е., чтобы программист мог непосредственно сам создавать и удалять переменные.
Сегодня Вы получите ответы на свои вопросы... Начнем с немного формального определения: унарные операторы new и delete служат для управления свободной памятью. Что такое свободная память? Свободная память - это предоставляемая системой область памяти для объектов, время жизни которых напрямую управляется программистом. Программист создает объект с помощью ключевого слова new (переводится с английского как 'новый'), а уничтожает его, используя delete (переводится с английского как 'удалить').
В С++ оператор new принимает следующие формы:
new имя_типа; new имя_типа (инициализатор); new имя_типа [выражение];В каждом случае происходит по крайней мере два эффекта. Во-первых, выделяется надлежащий объем свободной памяти для хранения указанного типа. Во-вторых, возвращается базовый адрес объекта (в качестве значения оператора new ). Когда память недоступна, оператор new возвращает значение 0 (NULL). Следовательно, мы можем контролировать процесс успешного выделения памяти оператором new. Рассмотрим следующий пример использования оператора new:
int *p, *q; p=new int (5); //выделили память и инициализировали q=new int [10]; //получаем массив от q[0] до q[9]В этом фрагменте указателю на целое р присваивается адрес ячейки памяти, полученный при размещении целого объекта. Место в памяти, на которое указывает р, инициализируется значением 5. Такой способ обычно не используется для простых типов вроде int, так как гораздо удобнее и естественнее объявить переменную привычным для нас образом. А вот использование примера с указателем q на массив встречается значительно чаще. Это, так называемые, динамические массивы (пример использования динамического массива приводится в конце даного материала).
Оператор delete уничтожает объект, созданный с помощью new, отдавая тем самым распределенную память для повторного использования. Оператор delete может принимать следующие формы:
delete выражение; delete [] выражение;Первая форма используется, если соответствующее выражение new размещало не массив. Во второй форме присутствуют пустые квадратные скобки, показывающие, что изначально размещался массив объектов. Оператор delete не возвращает значения, поэтому можно сказать, что возвращаемый им тип - void. Рассмотрим пример, который использует указанные конструкции для динамического распределения памяти.
/*Программа вычисляет среднее арифметическое элементов динамического массива. Размерность массива задается пользователем!*/#include <iostream.h> //функция, где и будет вычисляться среднее арифметическое элементов массиваdouble avg_arr(const int[], int );void main(){ int *data; //переменная - указатель на целое int size; //здесь будем хранить размер массива//строка выводит на экран надпись - Введите размер массива cout<<" Enter size of array:"; //запросили у пользователя информацию относительно размера массива cin>>size; data=new int[size]; /* здесь data используется в качестве базового адреса динамически размещаемого массива с количеством элементов задаваемым значением size *///организуем ввод элементов массива for (int j=0; j<size;j++) { cout<<"Enter A["<<j<<"]="; cin>>data[j]; }//выводим результат cout<<" The avarage sum is "<<avg_arr(data,size)<<" "; //и, главное правило при работе с указателями, не забываем освободить память!!! delete[] data;}//функция производит подсчет среднего арифметического элементов массиваdouble avg_arr(const int a[], int size){ int sum=0; for (int i=0; i<size; i++) sum+=a[i];//преобразуем sum к double, иначе получили бы только целую часть от деления return double (sum)/size; }