IB001 – Seminární skupiny 6, 7 a 24

Týden 14

Práce s dynamickou pamětí

Všechna data, jak byla používána doteď, obyčejné (primitivní) proměnné, pole, struktury, byla ukládána ve statické paměti programu, tj. velikost takové paměti nebylo možné po vytvoření (definici) měnit (zvětšit, zmenšit). Jazyk C, ale také nabízí možnost jak pracovat s daty, jejichž velikost se může během běhu programu měnit.
Představte si např. pole, do kterého chcete napočítat všechny prvky fibonacciho posloupnosti, které jsou menší než uživatelem zadaný limit. Mohli byste nejprve použít algoritmus, který v posloupnosti počet prvků menších než limit spočítá, ale praktičtější je si vypočítané prvky ihned ukládat do paměti, např. do dynamického pole.

Operátor sizeof

Operátor sizeof lze použít k zjištění, kolik bytů v paměti počítače datový typ (např. int, float, double, struktura) zabírá.
Příklad:

#include <stdlib.h>

// Pro ulozeni poctu byte se v C pouziva typ size_t, ktery je celocisleny a je definovany v stdlib.h
size_t si = sizeof(int);
size_t sd = sizeof(double);

printf("Velikost int je %d, velikost double je %d", si, sd);

Nebo:

typedef struct
{
    double r;
    double i;
} complex;

printf("Velikost typu complex je %d", sizeof(complex));

Funkce malloc, calloc a free

K alokaci (získání paměti z OS - operačního systému) dynamické se v jazyce C používá funkce malloc. Funkce malloc má jediný parametr, kterým je velikost paměti, kterou program požaduje po OS, v bytech. Když už program paměť nepotřebuje, vrátí ji operačnímu systému zpět pomocí funkce free.
Příklad níže alokuje pamět pro jednorozměrné pole celých čísel (int) o velikosti 10 prvků:

int * pole;
// k vypoctu velikosti pole v pameti se pouzije operator sizeof, zjisti se velikost typu prvku pole
pole = malloc(10 * sizeof(int));
// program vyuziva pole
pole[0] = 1;
pole[1] = 2;
...
for (int i = 0; i < 10; i++)
{
    printf("%d", pole[0]);
}
...
// program uvolni pamet
free(pole);

Pokud by funkce malloc nebyla úspěšná, např. v OS došla paměť, vrátí hodnotu NULL.
Pokud bychom chtěli alokovanou pamět ihned vynulovat (po bytech), můžeme paměť alokovat pomocí funkce calloc. Uvolnění paměti získané pomocí calloc se také provádí funkcí free.

Funkce realloc

Je-li potřeba změnit velikost (zmenšit i zvětšit) předem alokovaného paměťového bloku, lze to udělat voláním funkce realloc. Funkce realloc má dva parametry, kde prvním je ukazatel na původní alokovanou paměť a druhým je nová velikost alokované paměti.

 

Pokud předem alokovaný blok paměti zmenšíme, nemůžeme již přistupovat k datům v oblasti, o kterou jsme blok zmenšili. Naopak, pokud paměťový blok zvětšíme, nestane se, že bychom přišli o nějaká doposud (v bloku) uložená data. Pozor, v každém případě se ale může stát, že nový paměťový blok bude umístěný v paměti počítače jinde, než ten starý.