Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вказівники та посилання.docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
857.42 Кб
Скачать

11. Доступ до ділянок динамічної пам'яті

Вказівники часто використовують для роботи з динамічною пам'яттю.

Доступ до виділених ділянок динамічної пам'яті (динамічних змінних) можливий тільки через вказівники.

При визначенні вказівника бажано виконати його ініціалізацію (присвоєння початкового значення). Використання неініціалізованого вказівника приводить до помилки.

Ініціалізація вказівника полягає в виділенні ділянки динамічної пам'яті і присвоєння її адреси вказівнику:

int *n= new int; - виділення динамічної пам'яті, достатньої для розміщення величини типу int і запис адреси цієї ділянки в змінну n або int *n; (оголошується вказівник n) n = new int; (виділяється пам'ять для цілого числа і n робиться вказівником на цю пам'ять). Наступний код показує, як виділити пам'ять для величин з плаваючою точкою подвійної точності: double - double *d; d = new double.

int *m=new int (20) - аналогічно попередньому, але з ініціалізацією динамічної змінної значенням 20

int *z=new int [10] - виділення пам'яті для масиву з 10 елементів

Приклад 18

#include <windows.h>

#include <clocale>

#include <stdio.h>

void main()

{

setlocale (LC_CTYPE,"rus");

int *po;

// зробити po вказівником на нове ціле

po = new int;

*po = 25;

printf("Значення *po: %d\n", *po);

system("pause");

}

Скомпілюйте наведений приклад.

Як і чому він так працює? Коли виконується функція main(), виділяється пам'ять і ініціалізується вказівник, щоб він вказував на цю пам'ять. Коли блоку коду завершується, виділена пам'ять залишається недоторканою і вказівник po все ще вказує на неї, тобто, динамічне виділення відрізняється тим, що пам'ять, яка була виділена не звільняється після завершення блоку коду.

З пам'яттю завжди існують складнощі і в даному випадку досить серйозні, але ці складнощі можна з легкістю обійти. Проблема полягає в тому, що не дивлячись на те, що пам'ять, яка була виділена динамічно, залишається недоторканою, вона ніколи не звільняється автоматично. Пам'ять буде залишатися виділеною до тих пір, поки ви не скажете комп'ютеру що вам вона більше не потрібна. Проблема в тому, що якщо ви не скажете системі, що пам'ять вам більше не потрібна, вона буде займати місце, яке, можливо, необхідно іншим додаткам або частинам вашої програми. Зокрема це може призвести до збою системи через використання всієї доступної пам'яті, тому це дуже важливо.

12. Звільнення пам'яті

Звільнення пам'яті, виділеної за допомогою операції new коли вона вам більше не потрібна, робиться дуже просто:

delete po;

При цьому змінна-вказівник зберігається і може ініціалізуватися повторно.

З цим все. Ви повинні бути обережні, оскільки потрібно передавати правильний вказівник, вказівник який вказує саме на ту область пам'яті яку ви виділяли а не на незрозуміле сміття. Спроба звільнити пам'ять (за допомогою delete), яка вже була звільнена небезпечна і може призвести до збою програми. Тому наступний оновлений приклад показує як це робити правильно без даремного витрачання пам'яті:

Приклад 19

#include <windows.h>

#include <clocale>

#include <stdio.h>

void main()

{

setlocale (LC_CTYPE,"rus");

int *po;

// зробити po вказівником на нове ціле

po = new int;

*po = 25;

printf("Значення *po: %d\n", *po);

delete po;

system("pause");

}

Скомпілюйте наведений приклад.

Якщо ви не видалите пам'ять, то отримаєте так званий "витік пам'яті", коли пам'ять поступово витікає і не може бути повернута, поки програма не закриється.

Керуючи динамічними змінними необхідно:

а) явно створювати і знищувати динамічні змінні та об'єкти;

б) для кожного динамічного об'єкта організовувати принаймні один вказівник, який буде забезпечувати доступу до самого об'єкта.

І останнє попередження щодо масивів: якщо ви виділили пам’ять для масиву з використанням оператору new, як показано в наступному прикладі:

int *p;

p = new int[6];

то повинні потім видалити його з допомогою оператора:

delete[] p;

Зверніть увагу на [] після delete. Це повідомляє компілятор про те, що видаляється цілий масив, а не лише один елемент. Ви повинні використовувати цей метод коли мова йде про масив. В результаті ви отримаєте звільнення пам’яті.

Зауваження: ви не повинні звільняти пам’ять, якщо вона виділялась не через new.