přejít na obsah přejít na navigaci

Linux E X P R E S, Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie (2)

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.

Nahoru

Přidat téma diskuse

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz

Eduard Boldižár

Eduard Boldižár

Som redaktorom stránky astrotech.cz. Mám 25 rokov. Medzi moje záľuby patrí astronómia, sci-fi literatúra a programovanie.


  • Distribuce: ubuntu
  • Grafické prostředí: unity



Public Relations

Řešení QNAP typu all-flash

Eva FišerováNeustále rostoucí nároky na výkon, odezvu a propustnost vedou ke zvyšování podílu flash technologií nejen v datových centrech. Dnes typické hybridní úložné systémy jsou tak nahrazovány úložišti typu all-flash, která nabízí velmi nízké latence, miliony IOPS a přitom jsou stále dostupnější. Řešení all-flash od QNAP jsou založena na systému ZFS s optimalizačními technologiemi SSD, díky nimž mohou efektivně nahradit hybridní pole se stejnými náklady na úložiště.

Pokračování ...


Redakční blog

Pavel Fric

Pavel Fric, 10. April

Zapojte se do tvorby distribuce Mageia

Podílejte se na vytváření balíčků pro Mageiu, dělejte, co je potřeba, staňte se baličem


Pavel Fric

Pavel Fric, 13. March

Lollypop

Lollypop je hudební přehrávač navržený, jak ukazuje jeho podoba, aby výborně zapadl do pracovního...


Pavel Fric

Pavel Fric, 26. February

QElectroTech

Kreslení elektrotechnických i jiných výkresů


Všechny blogy »