Операторы выделения памяти new и delete.
Операция выделения памяти new
С помощью вышеозначенной операции мы можем себе позволить выделять память
динамически - т. е. на этапе выполнения программы.
Часто выражение, содержащее операцию new, имеет следующий вид:
указатель_на_тип_= new имя_типа (инициализатор) |
Инициализатор - это необязательное инициализирующее выражение, которое
может использоваться для всех типов, кроме массивов.
При выполнении оператора
создаются 2 объекта: динамический безымянный объект и указатель на него с
именем ip, значением которого является адрес динамического объекта. Можно
создать и другой указатель на тот же динамический объект:
Если указателю ip присвоить другое значение, то можно потерять доступ к
динамическому объекту:
int *ip=new (int);
int i=0;
ip=&i;
|
В результате динамический объект по-прежнему будет существовать, но
обратиться к нему уже нельзя. Такие объекты называются мусором.
При выделении памяти объект можно инициализировать:
Можно динамически распределить память и под массив:
double *mas = new double [50]; |
Далее с этой динамически выделенной памятью можно работать как с обычным
массивом:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void main(){
srand(time(NULL));
int size;
int * dar;
// запрос размера массива с клавиатуры
cout<<"Enter size:\n";
cin>>size;
//выделение памяти под массив с количеством элементов size
dar=new int [size];
if(!dar){
cout<<"Sorry, error!!!";
exit(0);// функция организует выход из программы
}
// заполнение массива и показ на экран
for(int i=0;i<size;i++){
dar[i]=rand()%100;
cout<<dar[i]<<"\t";
}
cout<<"\n\n";
}
|
В случае успешного завершения операция new возвращает указатель со значением,
отличным от нуля.
Результат операции, равный 0, т.е. нулевому указателю NULL, говорит о
том, что не найден непрерывный свободный фрагмент памяти нужного размера.
Операция освобождения памяти delete
Операция delete освобождает для дальнейшего использования в программе
участок памяти, ранее выделенной операцией new:
delete ip; // Удаляет динамический объект типа int,
// если было ip = new int;
delete [ ] mas; // удаляет динамический массив длиной 50, если было
// double *mas = new double[50];
|
Совершенно безопасно применять операцию к указателю NULL. Результат же
повторного применения операции delete к одному и тому же указателю не определен.
Обычно происходит ошибка, приводящая к зацикливанию.
Чтобы избежать подобных ошибок, можно применять следующую конструкцию:
int *ip=new int[500];
. . .
if (ip){
delete ip; ip=NULL;
}
else
{
cout <<" память уже освобождена \n";
}
|
В наш, вышеописанный пример, мы теперь можем добавить освобождение памяти.
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void main(){
srand(time(NULL));
int size;
int * dar;
// запрос размера массива с клавиатуры
cout<<"Enter size:\n";
cin>>size;
//выделение памяти под массив с количеством элементов size
dar=new int [size];
if(!dar){
cout<<"Sorry, error!!!";
exit(0);// функция организует выход из программы
}
// заполнение массива и показ на экран
for(int i=0;i<size;i++){
dar[i]=rand()%100;
cout<<dar[i]<<"\t";
}
cout<<"\n\n";
// освобождение памяти
delete[]dar;
}
|