Linux E X P R E S

Facebook

Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie (2)

cplusplus.png

Keď budete chcieť vrátiť pointer ako návratovú hodnotu funkcie, tak musíte myslieť na jednú dôležitú vec, pamäť. Neviažte pointer na lokálnu premennú, ale pre pointer získajte dynamický pridelenú pamäť.


Nezabudnite na pamäť

V minulom článku sme rozoberali, ako môže funkcia vrátiť pointer ako návratovú hodnotu. Avšak sme zabudli rozobrať jednú dôležitú záležitosť a to pamäť. Priznám sa bez mučenia, že som si v zmienenom článku neuvedomil nutnosť ošetrenia pamäte pre pointer. Aspoň sa môžete poučiť z mojej chyby. Poďme si ukázať jednoduchý príklad, na ktorom budeme demonštrovať tento kritický problém.

#include <iostream>
using namespace std;

int* scitaj(int cislo1, int cislo2)
{
    int vysledok = cislo1 + cislo2;
    int *ptr=&vysledok;
    return ptr;
}

int main()
{
    int volba1,volba2;

    cout << "Zadajte prve cislo, ktore chcete scitat od 1 do 99: ";
    cin >> volba1;

    if(volba1 < 1 || volba1 > 99)
    {
        cout << "Nepripustna operacia\n";
        return 0;
    }

    cout << "Zadajte druhe cislo, ktore chcete scitat od 1 do 99: ";
    cin >> volba2;

    if(volba2 < 1 || volba2 > 99)
    {
        cout << "Nepripustna operacia\n";
        return 0;
    }

    int *num=scitaj(volba1,volba2);

    cout << "Vysledok scitania cisiel "<<volba1<< " a " <<volba2<<" je: "<<*num<<"\n";
    return 0;
}

Výsledok programu:

Zadajte prve cislo, ktore chcete scitat od 1 do 99: 44
Zadajte druhe cislo, ktore chcete scitat od 1 do 99: 79
Vysledok scitania cisiel 44 a 79 je: 123

Ak tento program spustíte, tak v drvivej väčšine vám vypíše správny výsledok. Avšak, zdanie klame. Chyba pramení v tom, že my sme deklarovali lokálnu premennú vo funkcii, ktorá prestane existovať skončením bloku funkcie. To, že dostaneme správny výsledok výpočtu, je vecou kompilátora. Ak by sme mali zložitejší program s mnohými premennými, tak by došlo k deklarácii inej premennej v pamäťovom priestore pôvodnej lokálnej premennej.

Skúsme teraz pointeru vyhradiť pamäť s pomocou new int. Čiže pointer nebude odkazovať na lokálnu premennú, ale na nový pridelený blok pamäte o veľkostí zvoleného typu premennej. Potom už nám nič nebráni v tom, aby sme priradili hodnotu do pointeru odkazujúceho na vyhradený blok pamäte.

#include <iostream>
using namespace std;

int* scitaj(int cislo1, int cislo2)
{
    int vysledok = cislo1 + cislo2;
    int *ptr = new int;
    *ptr=vysledok;
    return ptr;
}

int main()
{
    int volba1,volba2;

    cout << "Zadajte prve cislo, ktore chcete scitat od 1 do 99: ";
    cin >> volba1;

    if(volba1 < 1 || volba1 > 99)
    {
        cout << "Nepripustna operacia\n";
        return 0;
    }

    cout << "Zadajte druhe cislo, ktore chcete scitat od 1 do 99: ";
    cin >> volba2;

    if(volba2 < 1 || volba2 > 99)
    {
        cout << "Nepripustna operacia\n";
        return 0;
    }

    int *num=scitaj(volba1,volba2);

    cout << "Vysledok scitania cisiel "<<volba1<< " a " <<volba2<<" je: "<<*num<<"\n";
    return 0;
}

Výsledok programu:

Zadajte prve cislo, ktore chcete scitat od 1 do 99: 71
Zadajte druhe cislo, ktore chcete scitat od 1 do 99: 25
Vysledok scitania cisiel 71 a 25 je: 96

No fajn, ale čo ak máme v programe mnoho premenných a bez uvoľnenia pamäte už nevyužívaných premenných sa nám rýchlo spotrebuje pamäťový priestor? Preto je dobrým zvykom uvoľniť pamäť, ak ju už nepotrebujeme. Nato nám slúži príkaz delete. V našom jednoduchom príklade ho prakticky pridáme na konci programu. To ale neznamená, že v zložitejšom programe budete uvoľňovať pamäť až na konci programu. Vždy musíte zvážiť, kedy už nepotrebujete využívať premennú a tak s pomocou príkazu delete získate cenný pamäťový priestor.

#include <iostream>
using namespace std;

int* scitaj(int cislo1, int cislo2)
{
    int vysledok = cislo1 + cislo2;
    int *ptr = new int;
    *ptr=vysledok;
    return ptr;
}

int main()
{
    int volba1,volba2;

    cout << "Zadajte prve cislo, ktore chcete scitat od 1 do 99: ";
    cin >> volba1;

    if(volba1 < 1 || volba1 > 99)
    {
        cout << "Nepripustna operacia\n";
        return 0;
    }

    cout << "Zadajte druhe cislo, ktore chcete scitat od 1 do 99: ";
    cin >> volba2;

    if(volba2 < 1 || volba2 > 99)
    {
        cout << "Nepripustna operacia\n";
        return 0;
    }

    int *num=scitaj(volba1,volba2);

    cout << "Vysledok scitania cisiel "<<volba1<< " a " <<volba2<<" je: "<<*num<<"\n";
    delete num;
    return 0;
}

Uvoľnenie pamäte dosiahneme príkazom delete num;. Upozornenie, uvoľniť pamäť môžete len pri dynamicky pridelenej pamäte s pomocou operátora new. Zároveň ak na pridelenú pamäť ukazuje viacero pointerov, stačí uvoľniť pamäť cez jeden pointer.

Diskuze (0) Nahoru