Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
47
Добавлен:
12.02.2016
Размер:
147.46 Кб
Скачать

2.3 Використання функцій malloc(), calloc(), realloc() та free()

Функція

void *malloc(size_t size);

виділяє в динамічній пам’яті блок розміром size байт. Виділена пам’ять зайнята довільними даними – “сміттям”. Якщо пам’ять виділена успішно, то malloc повертає нетипізований вказівник на початок виділеного блока пам'яті, а інакше NULL.

Функція

void *calloc(size_t numb, size_t size);

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

Функція

void *realloc(void *ptr, size_t size);

встановлює у size розмір блока пам'яті, виділеного раніше функціями malloc, calloc або realloc, на початок якого вказує ptr.

Якщо ptr == NULL, то функція realloc діє аналогічно функції malloc з параметром size.

Якщо зміна розміру блока пам'яті відбулася успішно, то функція realloc повертає вказівник на початок зміненого блока (у разі, якщо адреса блока міняється, дані копіюються в ділянку пам'яті за новою адресою). Адреса блока може і не змінитися. У будь-якому випадку за старою адресою до даних звертатися не можна – потрібно перевірити, чи адреса не змінилася. Якщо ж розмір блока змінити не вдалося, то функція realloc повертає NULL, а до даних можна продовжувати звертатися за старою адресою.

Функція

void free(void *ptr);

звільняє блок пам'яті, на початок якого вказує ptr. Добрим стилем є звільнення пам'яті щоразу, як вона стає непотрібною. Після завершення роботи програми пам'ять буде звільнено, тому в невеликих програмах звільнення пам'яті є питанням доброго стилю. Однак, у великих програмах є небезпека «просочування пам'яті».

Приклад. Наступна програма приймає від користувача цілі числа та записує їх у динамічний масив. Спочатку виділяється місце під N елементів типу int. Далі, якщо кількість введених чисел перевищить N, то виділяємо вдвічі більший обсяг пам'яті. Програма працюватиме коректно, якщо користувач задасть не більше, ніж 2N цілих чисел. Ввід чисел буде припинено, якщо користувач задасть 0.

#include "stdafx.h"

#include <iostream>

#include <conio.h>

using namespace std;

int main()

{

int N = 6; /* спочатку виділяємо пам'ять для збереження N цілих чисел; оскільки calloc повертає вказівник на void, а працювати потрібно з int, то слід явно привести результат calloc до типу int* */

int *p = (int*)calloc(N,sizeof(int));

if(p) { /* якщо пам'ять виділена успішно */

int *pp = p, *p2 = NULL; /* оголошуємо «робочі» вказівники */

int i = -1, k = -1; /* і – будемо використовувати як індекс в масиві, а k – допоміжна змінна */

do { /* поки користувач вводить ненульові числа, їх будемо записувати в динамічний масив */

i++; k++;

if(k>(N-1)) /* якщо введено більше, ніж N чисел */

{ /* збільшуємо розмір динамічного масиву вдвічі*/

p2 = (int*)realloc(p,2*N*sizeof(int));

if(!p2) /* якщо не вдалося виділити пам'ять, то виходимо з циклу */

{

i--;

cout<<"Sorry, not enouph memory";

break;

}

else

{

/* допоміжну змінну k знову встановлюємо в її початкове значення і встановлюємо «робочий» вказівник pp на нову адресу динамічного масиву */

pp = p2;

k = -1;

}

}

cout<<"Enter a number"<<endl;

cin>>pp[i];

} while (pp[i]);

/* Якщо p2!=NULL, то виділялася додаткова пам'ять, і тоді «робочому» вказівнику pp присвоюємо значення p2, а інакше – значення p (тобто, вказівника на початок блока пам'яті, що була виділена від самого початку функцією calloc)*/

p2?pp=p2:pp=p;

/* вивід елементів динамічного масиву на екран */

for (int j = 0; j < i; j++) cout<<pp[j]<<"\t";

}

_getch();

return 0;

}

Соседние файлы в папке ОП (лаби) [1-13]