unsigned short int * pPointer; pPointer = new unsigned short int;
Или выполнить те же действия, но в одной сороке:
unsigned short int * pPointer = new unsigned short int;
В каждом случае указатель pPointer будет указывать на ячейку памяти в области динамического обмена, содержащую значение типа unsigned short. Теперь pPointer можно использовать как любой другой указатель на переменную этого типа. Чтобы занести в выделенную область памяти какое-нибудь значение, напишите такую строку:
*pPointer = 72;
Эта строка означает следующее: "записать число 72 в память по адресу, хранящемуся в pPointer".
Ввиду того что память является ограниченным ресурсом, попытка выделения памяти оператором new может оказаться неудачной. В этом случае возникнет исключительная ситуация, которая рассматривается на занятии 20.
Когда память, выделенная под переменную, больше не нужна, ее следует освободить. Делается это с помощью оператора delete, после которого записывается имя указателя. Оператор delete освобождает область памяти, определенную указателем. Необходимо помнить, что указатель, в отличие от области памяти, на которую он указывает, является локальной переменной. Поэтому после выхода из функции, в которой он был объявлен, этот указатель станет недоступным. Однако область памяти, выделенная оператором new, на которую сослался указатель, при этом не освобождается. В результате часть памяти окажется недоступной. Программисты называют такую ситуацию утечкой памяти. Такое название полностью соответствует действительности, поскольку до завершения работы программы эту память использовать нельзя, она как бы "вытекает" из вашего компьютера.
Чтобы освободить выделенную память, используйте ключевое слово delete, например:
delete pPointer;
На самом деле при этом происходит не удаление указателя, а освобождение области памяти по адресу, записанному в нем. При освобождении выделенной памяти с самим указателем ничего не происходит и ему можно присвоить другой адрес. Листинг 8.4 показывает, как выделить память для динамической переменной, использовать ее, а затем освободить.
Предупреждение: Когда оператор delete применяется к указателю, происходит освобождение области динамической памяти, на которую этот указатель ссылается. Повторное применение оператора delete к этому же указателю приведет к зависанию программы. Рекомендуется при освобождении области динамической памяти присваивать связанному с ней указателю нулевое значение. Вызов оператора delete для нулевого указателя пройдет совершенно безболезненно для программы, например:
Animal *pDog = new Animal;
delete pDog; // освобождение динамической памяти
pDog = 0 // присвоение указателю нулевого значения
// ...
delete pDog; // бессмысленная, но совершенно безвредная строка
Листинг 8.4. Выделение, использование и освобождение динамической памяти
1; // Листинг 8, 4,
2; // Выделение, использование и освобождение динамической памяти 3;
4: #include
5: int main()
6: {
7: int localVariable = 5;
8: int * pLocal= &localVariable;
9: int * pHeap = new int;
10: рНеар = 7;
11: cout << "localVariable: " << localVariable << "\n";
12: cout << "*pLocal: " << *pLocal << "\n";
13: cout << "*pHeap; " << *pHeap << "\n";
14: delete рНеар;
15: рНеар = new int;
16: *pHeap = 9;
17: cout << "*pHeap: " << *pHeap << "\n";
18: delete рНеар;
19: return 0;
20: }
Результат:
localVariable: 5
*pLocal: 5
*pHeap: 7
*pHeap: 9
Анализ:В строке 7 объявляется и инициализируется локальная переменная localVariable. Затем объявляется указатель, которому присваивается адрес этой переменной (строка 8). В строке 9 выделяется память для переменной типа int и адрес выделенной области помещается в указатель рНеар. Записав по адресу, содержащемуся в рНеар, значение 7, можно удостовериться в том, что память была выделена корректно (строка 10). Если бы память под переменную не была выделена, то при выполнении этой строки появилось бы сообщение об ошибке.
Чтобы не перегружать примеры излишней информацией, мы опускаем всякого рода проверки. Однако во избежание аварийного завершения программы при решении реальных задач такой контроль обязательно должен выполняться.
В строке 10, после выделения памяти, по адресу в указателе записывается значение 7. Затем в строках 11 и 12 значения локальной переменной и указателя pLocal выводятся на экран. Вполне понятно, почему эти значения равны. Далее, в строке 13, выводится значение, записанное по адресу, хранящемуся в указателе рНеар. Таким образом, подтверждается, что значение, присвоенное в строке 10, действительно доступно для использования.
Читать дальше