АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Инициализация указателей

Читайте также:
  1. Взаимосвязь массивов и указателей
  2. Знаки маршрута эвакуации и указателей направления к ближайшему выходу или площадке безопасности
  3. Инициализация bluetooth-соединения
  4. Инициализация и присваивание структур.
  5. Инициализация массивов.
  6. Инициализация портов
  7. Использование указателей разных типов
  8. Объявления и инициализация переменных указателей
  9. Передачи значений указателей
  10. Последовательное и четкое применение знаков маршрутов эвакуации и указателей направления

Указатели чаще всего используют при работе с динамической памятью, называе­мой некоторыми эстетами кучей (перевод с английского языка слова heap). Это свободная память, в которой можно во время выполнения программы выделять место в соответствии с потребностями. Доступ к выделенным участкам динами­ческой памяти, называемым динамическими переменными, производится только через указатели. Время жизни динамических переменных – от точки создания до конца программы или до явного освобождения памяти. В C++ используется два способа работы с динамической памятью. Первый использует семейство функций mallос и достался в наследство от С, второй использует операции new и delete.

При определении указателя надо стремиться выполнить его инициализацию, то есть присвоение начального значения. Непреднамеренное использование неини­циализированных указателей – распространенный источник ошибок в програм­мах. Инициализатор записывается после имени указателя либо в круглых скоб­ках, либо после знака равенства.

Существуют следующие способы инициализации указателя:

1. Присваивание указателю адреса существующего объекта:

· с помощью операции получения адреса:

int a = 5; // целая переменная

int* р = &а; //в указатель записывается адрес а

int* p (&а); // то же самое другим способом

· с помощью значения другого инициализированного указателя:

int* r = р;

· с помощью имени массива или функции, которые трактуются как адрес:

int b[10]; // массив

int* t = b; // присваивание адреса начала массива

void f(int a){ /*... */ } // определение функции

void (*pf)(int); // указатель на функцию

Pf = f; // присваивание адреса функции

 

2. Присваивание указателю адреса области памяти в явном виде:

char* vp = (char *)0xB8000000;

Здесь 0хВ8000000 – шестнадцатеричная константа, (char *) – операция приве­дения типа: константа преобразуется к типу «указатель на char».

3. Присваивание пустого значения:

int* suxx = NULL;

int* rulez = 0;

В первой строке используется константа NULL, определенная в некоторых за­головочных файлах С как указатель, равный нулю. Рекомендуется использо­вать просто 0, так как это значение типа int будет правильно преобразовано стандартными способами в соответствии с контекстом. Поскольку гарантиру­ется, что объектов с нулевым адресом нет, пустой указатель можно использо­вать для проверки, ссылается указатель на конкретный объект или нет.

4. Выделение участка динамической памяти и присваивание ее адреса указателю:

· с помощью операции new:

int* n = new int; // 1

int* m = new int (10); // 2

int* q = new int [10]; // 3

· с помощью функцииmalloc[1]:

int* u = (int *)malloc(sizeof(int)); // 4

 

В операторе 1 операция new выполняет выделение достаточного для размещения величины типа int участка динамической памяти и записывает адрес начала это­го участка в переменную n. Память под саму переменную n (размера, достаточно­го для размещения указателя) выделяется на этапе компиляции.

В операторе 2, кроме описанных выше действий, производится инициализация выделенной динамической памяти значением 10.

В операторе 3 операция new выполняет выделение памяти под 10 величин типа int (массива из 10 элементов) и записывает адрес начала этого участка в пере­менную q, которая может трактоваться как имя массива. Через имя можно обра­щаться к любому элементу массива. Если память выделить не удалось, по стандарту должно порождаться исключе­ние bad_alloc. Старые версии компиляторов могут возвращать 0.

В операторе 4 делается то же самое, что и в операторе 1, но с помощью функции выделения памяти malloc, унаследованной из библиотеки С. В функцию переда­ется один параметр – количество выделяемой памяти в байтах. Конструкция (int*) используется для приведения типа указателя, возвращаемого функцией, к требуемому типу. Если память выде­лить не удалось, функция возвращает 0.

Операцию new использовать предпочтительнее, чем функцию malloc, особенно при работе с объектами.

Освобождение памяти, выделенной с помощью операции new, должно выпол­няться с помощью delete, а памяти, выделенной функцией malloc – посредством функции free. При этом переменная-указатель сохраняется и может инициали­зироваться повторно. Приведенные выше динамические переменные уничтожа­ются следующим образом:

delete n; delete m; delete []q; free (u):

Если память выделялась с помощью new[], для освобождения памяти необходимо применять delete[]. Размерность массива при этом не указывается. Если квад­ратных скобок нет, то никакого сообщения об ошибке не выдается, но помечен как свободный будет только первый элемент массива, а остальные окажутся не­доступны для дальнейших операций. Такие ячейки памяти называются мусором.


1 | 2 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.004 сек.)