Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

9.5.4. Функції виділення та звільнення пам'яті у мові програмування с

Мова програмування C не містить операторів new або delete. Замість них у мові С використовують бібліотечні функції, призначені для виділення і звільнення пам'яті. З метою сумісності, мова C++, як і раніше, підтримує С-систему динамічного розподілу пам'яті і не дарма: у С++-програмах все ще використовують С-орієнтовані засоби динамічного розподілу пам'яті. Тому їм варто приділити певну увагу.

Ядро С-системи динамічного розподілу пам'яті становлять функції malloc() і free(). Функція malloc() призначена для виділення пам'яті, а функція free() – для її звільнення. Іншими словами, кожного разу, коли за допомогою функції malloc() робиться запит, частина вільної пам'яті виділяється відповідно до цього запиту. Під час кожного виклику функції free() відповідна область пам'яті повертається системі. Будь-яка програма, яка використовує ці функції, повинна містити заголовок <cstdlib>.

Функція malloc() має такий прототип:

void *malloc(size_t num_bytes);

У цьому записі num_bytes означає кількість байтів запрошуваної пам'яті. Тип size_t є різновид цілочисельного типу без знаку. Функція malloc() повертає покажчик типу void, який відіграє роль узагальненого покажчика. Щоб з цього узагальненого покажчика отримати покажчик на потрібний Вам тип, необхідно використовувати операцію приведення типів. Внаслідок успішного виклику функція malloc() поверне покажчик на перший байт області пам'яті, виділеної з "купи". Якщо для задоволення запиту вільної пам'яті в системі недостатньо, функція malloc() повертає нульовий покажчик.

Функція free() виконує дію, зворотну дії функції malloc() тому, що вона повертає системі раніше виділену нею пам'ять. Після звільнення пам'ять можна знову використовувати подальшим зверненням до функції malloc(). Функція free() має такий прототип:

void free(void *ptr);

У цьому записі параметр ptr є покажчиком на пам'ять, раніше виділену за допомогою функції malloc(). Ніколи не варто викликати функцію free() з недійсним аргументом; це може призвести до руйнування переліку областей пам'яті, що підлягають звільненню.

Використання функцій malloc() і free() продемонстровано у наведеному нижче коді програми.

Код програми 9.18. Демонстрація механізму використання функцій malloc() і free()

#include <iostream> // Для потокового введення-виведення

#include <cstdlib> // Для використання бібліотечних функцій

using namespace std; // Використання стандартного простору імен

int main()

{

int *izm;

double *jzm;

izm = (int *) malloc(sizeof(int)};

if(!izm) {

cout << "Виділити пам'ять не вдалося.\n";

return 1;

}

jzm = (double *) malloc(sizeof(double));

if(!jzm) {

cout << "Виділити пам'ять не вдалося.\n";

return 1;

}

*izm = 10;

*jzm = 100.123;

cout << *izm << " " << *jzm;

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

free(izm);

free(jzm);

getch(); return 0;

}

Хоча функції malloc() і free() повністю придатні для динамічного розподілу пам'яті, є ряд причин, згідно з якими у мові програмування C++ визначено власні засоби динамічного розподілу пам'яті:

  • по-перше, оператор new автоматично обчислює розмір області пам'яті, що виділяється, для заданого типу, тобто програмісту не потрібно використовувати оператор sizeof, а значить, наявна економія в коді програми і трудовитратах програміста. Але важливіше те, що автоматичне обчислення не допускає виділення неправильного об'єму пам'яті;

  • по-друге, С++-оператор new автоматично повертає коректний тип покажчика, що звільняє програміста від потреби використовувати операцію приведення типів;

  • по-третє, використовуючи оператора new, можна ініціалізувати об'єкт, для якого виділяється пам'ять.

Нарешті, як буде показано далі у цьому навчальному посібнику, програміст може створити власні версії операторів new і delete.

І останнє. Через можливість несумісності не варто змішувати функції malloc() і free() з операторами new і delete в одній програмі.

9.6. Зведена таблиця пріоритетів виконання С++-операторів

У табл|. 9.3 показано пріоритет виконання всіх С++-операторів (від вищого до найнижчого). Більшість операторів асоційована зліва направо. Але унарні оператори, оператори присвоєння і оператор "?" асоційовані справа наліво. Звернемо Вашу увагу на те, що ця таблиця містить декілька операторів, які ми поки не використовували в наших прикладах, оскільки вони належать до об'єктно-орієнтованого програмування (і описані нижче).

Табл. 9.3. Пріоритет С++--операторів

Найвищий

() [] -> :: .

! ~ ++ -- - * & sizeof new delete typeid

оператори приведення типу

.* ->*

* / %

+

<< >>

< <= > >=

== !=

&

^

&&



?:

= += -= *= /= %= >>= <<= &= ^= |=

Нижчий

,

Розділ 10. Поняття про структури і об'єднання даних

У мові програмування C++ визначено декілька складених типів даних, тобто типів, які складаються з двох або більше елементів. Такі складені типи даних як масив і перерахунок розглядалися раніше відповідно у розд. 6.4 і 9.4. З двома іншими – структурами і об'єднаннями – ми познайомимося у цьому розділі, а знайомство з ще одним складеним типом – класом – ми відкладемо до розд. 12. І, хоча структуровані та об'єднані типи даних призначено для задоволення різних програмних потреб, обидва вони є зручними засобами керування групами взаємопов'язаних між собою змінних. При цьому важливо розуміти, що створення структури (або об'єднання) означає створення нового визначеного програмістом типу даних. Сама можливість створення власних типів даних є ознакою потужності мови C++.

У мові програмування C++ структури та об'єднання мають як об'єктно-орієнтовані, так і не об'єктно-орієнтовані атрибути. У цьому розділі детально проаналізуємо тільки останні. Об'єкт­но-орієнтовані їх властивості будемо розглядати в наступному розділі після введення таких понять як класи і об'єкти.