После освобождения динамической памяти указатель получает адрес 0 (NULL) и операционная система помечает ее как свободную. В связи с этим не следует использовать указатели на освобожденную память.
Динамические массивы создаются во время выполнения программы. По ходу выполнения неоднократно может определяться размер массива, резервироваться память, обрабатываться и освобождаться.
Формат оператора new для динамического массива:
Тип указатель = new тип [размер];
Формат оператора delete для освобождения памяти занятой динамическим массивом:
delete [] указатель;
Размер в операторе newзаписывается в квадратных скобках и задает число элементов создаваемого массива. В результате выполнения оператора указатель получает адрес нулевого элемента. Следовательно, адрес каждого элемента находится указатель + индоксная, а значение по адресу хранящемуся в указателю, т.е.:
- * указатель + индоксная;
- *указатель[индоксная];
- указатель[индоксная];
В операторе delete размер не указывается, но наличие квадратных скобок является обязательным. Оператор освобождает память от всех элементов массива, а указатель теряет адрес нулевого элемента.
Пример использования операторов new и delete для динамического массива
#include <iostream>
using namespace std ;
int main ( )
{
// ввод размера массивов
int size ; cout << "Enter size of array -> " ; cin >> size ;
// выделение памяти под массивы
double* pdArray = new double [ size ] ;
int* piArray = new int [ size ] ;
// адреса элементов массивов
cout << "\nAddresses for double\n" ;
for ( int i = 0; i < size; i++ )
cout << ( pdArray + i ) << '\t' ;
cout << "\n\nAddresses for int\n" ;
for ( int i = 0; i < size; i++ )
cout << ( piArray + i ) << '\t' ;
// значения элементов массива целых чисел
cout << "\n\nValues of integer array\n" ;
for ( int i = 0; i < size; i++ )
{
* ( piArray + i ) = i * i ; //piArray[i]
cout << * ( piArray + i ) << "\t\t" ;
}
cout << endl ;
// освобождение памяти
delete [ ] piArray ; delete [ ] pdArray ;
return 0 ;
}
Если спецификатор constстоит перед именем типа, то объявляется указатель на константу.
Пример объявления указателя на константу
const char A = 'A' ;
const char* pC = &A ;
const char Z = 'Z' ; pC = &Z ;
Невозможно изменить значение переменной, на которую указывает указатель, но можно изменить значение самого указателя. Это полезно при передаче аргументов в функцию, когда аргументы нельзя изменить.
Если спецификатор const стоит непосредственно перед идентификатором указателя, то объявляется константный указатель.
Пример объявления константного указателя
char* const pCH = new char [ 40 ] ;
int * const pi = new int [100];
// константный указатель на константу
const char* const p = "constant pointer on a constant" ;
В этом случае, нельзя изменить значение указателя, но можно изменить значение того, на что он указывает. Указатели, которые объявлены константными, должны получить начальное значение при объявлении. Константный указатель всегда указывает на одну и ту же ячейку памяти.
Пример использования указателей со спецификатором const