Лекция 7 - Динамичний розподил памяти shov.ppt
- Количество слайдов: 33
Лекція Тема 7. Динамічний розподіл пам’яті (с) Гроза П. М. 1
Навчальні питання 1. Динамічне виділення пам’яті 2. Доповнення та вивільнення виділеної пам’яті (с) Гроза П. М. 2
Література 1. 2. 3. 4. Керниган Б. , Ритчи Д. Язык программирования Си ДПер. с англ. , 3 -е изд. , испр. — СПб. : "Невский Диалект", 2001. 352 с: ил. Язык програмирования С++. Лекция и упражнения. Учебник: Перевод с анг. /Стивен Прата – СПб. : ООО «Диа. Софт. ЮП» , 2005. -1104 с. Теренс Чан Системное програмирование на С++ для UNIX: пер. с англ. – К. : Издательская группа ВНV, 1997. – 592 с. Уэйк М. , Прата С. , Мартин Д. Язык Си Руководство для начинающих: Пер. с англ. . – М: Мир, 1988. -512 с. , ил. (с) Гроза П. М. 3
1. Динамічне виділення пам’яті (с) Гроза П. М. 4
ОП для роботи програми 1. 2. 3. 4. ОП для коду програми ОП для статичних даних ОП для динамічних даних (купа) ОП для стеку (с) Гроза П. М. 5
Розподіл пам'яті 1) 2) Автоматичний Динамічний ОП програми та її статичних даних у процесі виконання програми залишається незмінною ОП з купи виділяється та звільняється в процесі виконання програми Об‘єм ОП купи, для динамічного розміщення даних залежить від запиту програмою функціями calloc( ) та malloc( ) (с) Гроза П. М. 6
Моделі оперативної пам'яті в Сі 1) Крихітна (tiny model) 2) Мала (small model) 3) Середня (medium model) 4) Компактна (compact model) 5) Велика (large model) 6) Величезна (huge model) (с) Гроза П. М. 7
1) Крихітна оперативна пам'ять Використовується при дефіциті ОП Для коду програми, статичних даних, динамічних даних (купи) та стеку виділяється - 64 КБ (с) Гроза П. М. 8
2) Мала оперативна пам'ять Для програми Для стеку, купи і статичних даних - 64 КБ - по 64 КБ Модель приймається за умовчанням Використовується для рішення маленьких і середніх задач (с) Гроза П. М. 9
3) Середня оперативна пам'ять Розмір ОП для програми Стек, купа і статичні дані - 1 МБ - по 64 КБ Використовується для дуже великих програм і невеликих обсягів даних (с) Гроза П. М. 10
4) Компактна оперативна пам'ять Для програми Для даних Об‘єм статичних даних Розмір стека - 64 КБ - 1 МБ - 64 КБ <= 64 КБ Використовується для малих і середніх програм, з великим об‘ємом даних (с) Гроза П. М. 11
5) Велика оперативна пам'ять ОП для програми Для статичних даних Купа Використовується для великих задач Обмеження - окрема одиниця даних займає <= 64 КБ (с) Гроза П. М. - до 1 МБ - 64 КБ - до 1 МБ 12
6) Величезна оперативна пам'ять Аналогічна великій моделі Додатково - зняті обмеження на розмір окремої одиниці даних (с) Гроза П. М. 13
Функції динамічного розподілу пам’яті 1. malloc( ); - резервує пам'ять в байтах з ресурсу купи, умістом виділеного блоку є “мусор” 2. calloc( ); - резервує пам'ять в байтах з ресурсу купи, уміст виділеного блоку обнуляється Прототип в файлі stdlib. h (або alloc. h) (с) Гроза П. М. 14
1. 1. Функція malloc( ) Формат ü size; void* malloc(size_t size); - обсяг пам'яті в байтах, який необхідно виділити Повертає покажчик на n байт не ініціалізованої пам'яті NULL - якщо запит задовольнити не можна (с) Гроза П. М. 15
Приклад функції malloc( ) /* виділення під змінну *mas 150 одиниць типу char */ char *mas; if ((mas =(char *) malloc(sizeof(char)*150 ))==0) { printf("Помилка виділення пам'яті mas n"); exit(1); } (с) Гроза П. М. 16
Операція sizeof( ) - обраховує розмір пам’яті, необхідний для розміщення в ній виразів або змінних вказаного типу Застосовується до констант, типів або змінних Формат int sizeof (тип); Повертає Значення = кількості байт пам'яті, необхідних для представлення величини визначеного типу в конкретній ЕОМ (с) Гроза П. М. 17
1. 2 Функція calloc( ) Формат void* calloc(size_t n, size_t size); ü n - містить кількість необхідних комірок пам'яті ü size - розмір кожної комірки в байтах виділена пам'ять звільняється по завершенні роботи поточного програмного компоненту, або за допомогою функції Повертає ü покажчик на n байт не ініціалізованої пам'яті, адресу першого з них ü NULL - якщо запит задовольнити не можна (с) Гроза П. М. 18
Приклад функції сalloc( ) /* виділення під змінну *mas 150 одиниць типу char */ char *mas; if ((mas =( char *) calloc(150 , sizeof(char)))==0) { printf("Помилка виділення пам'яті mas n"); exit(1); } (с) Гроза П. М. 19
Рекомендації, що до використання динамічного розподілу пам'яті При роботі з функціями Не слід повертати як результат виконання адреси автоматичних (локальних) змінних функції Необхідно повернути адресу ОП, що виділена з купи Можлива помилка Подвійна вказівка на дані, розташовані у купі Зменшення об‘єму доступної ОП через не звільнення отриманої ОП (с) Гроза П. М. 20
Приклад /*Подвійна вказівка і зменшенням об‘єму доступної ОП - не звільнення ОП*/ #include
Питання? (с) Гроза П. М. 22
2. Доповнення та вивільнення виділеної пам’яті (с) Гроза П. М. 23
Функції realloc( ); - намагається зменшити або збільшити до визначеного розміру байт попередньо розподілену область пам'яті free(p); - звільняє область пам'яті, на яку вказує покажчик p, вертає пам'ять до купи (с) Гроза П. М. 24
2. 1 Функція realloc() Формат void* realloc(void *block, size_t size); block - указує на область пам'яті, що отримана за допомогою звертання до malloc( ), calloc( ) або realloc( ) ü size – розмір області пам'яті в байтах, до якої збільшується або зменшується раніше виділена пам'ять ü Якщо block = NULL, то realloc( ) працює як malloc( ) Повертає ü адресу перерозподіленої області пам'яті ü NULL - якщо запит задовольнити не можна, або size=0 (с) Гроза П. М. 25
Послідовність роботи realloc() 1) змінює розмір розподіленої пам'яті до size байт 2) копіюючи при необхідності її вміст у нове місце 3) повертає адресу початку перерозподіленої області пам'яті, що може відрізнятися від адреси вихідної області (с) Гроза П. М. 26
2. 2 Функція free(p) Формат ü free(p); p - ім'я покажчика, що посилається на пам'ять, що звільняється Покажчик p попередньо отримується за допомогою malloc() або calloc( ) Повертаєме значення відсутнє (с) Гроза П. М. 27
Особливості використання free(p) обмежень на порядок звільнення пам'яті немає вважається помилкою звільнення тих областей, які не були отримані за допомогою calloc( ) або malloc( ) не можна використовувати ті області пам'яті, які вже звільнені до звільнення збережіть необхідні дані з чарунок пам'яті (с) Гроза П. М. 28
Приклад void main() { int *p, j; randomize( ); /* Запит ОП для динамічного масиву з 10 елементів типу int */ p= (int*) malloc (10 * sizeof (int)); for (i = 0; i < 10; i++) p[i] = random(10); /* Звільння ОП */ free(p); /* Запит ОП для динамічного масиву з 15 елементів типу int */ p= (int*) сalloc (15, sizeof (int)); for (i = 0; i < 15; i++) p[i] = random(15); /* Звільння ОП */ free(p); } (с) Гроза П. М. 29
2. 3. Робота з великими масивами Розмір одного масиву даних <= 64 Кб В реальних задачах масиви можуть вимагати ОП >64 Кб Приклад ü Масив даних типу float з 300 х200 ü Для розміщення потребує 300 * 200 * 4 = 240000 байт (с) Гроза П. М. 30
Рішення проблеми Можна використовувати масив покажчиків і динамічне виділення ОП для кожного рядка матриці Рядок матриці повинен бути < 64 Кб Для виділення ОП з купи кожен рядок повинен мати свій покажчик ü для всіх рядків масиву оголосимо масив покажчиків, по одному для кожного рядка ü кожному рядку масиву виділимо ОП (с) Гроза П. М. 31
Приклад void main() { int *p[200], i, j; randomize( ); /* Запит ОП для рядків великого масиву */ for (i=0; i<200; i++) p[i] = (int*) malloc (300 * sizeof (int)); for (i = 0; i < 200; i++) for (j = 0; j < 300; j++ ) { *(p[i] + j ) = random(100); printf("%3 d", *(p[i] + j )); if ( (j + 1) % 20 == 0 ) printf ("n" ); } /* Звільння ОП рядків великого масиву */ for ( i=0; i < 200; i++ ) free(p[i]); } (с) Гроза П. М. 32
Питання? (с) Гроза П. М. 33