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

Urychlování technologických inovací s úložištěm NAS uznávaným již 10 let

WDProduktová řada disků WD Red, které jsou speciálně určeny a optimalizovány pro využití v NAS zařízeních, slaví v letošním roce 10. výročí svého vzniku. To je příležitost, připomenout si, co disky WD Red, WD Red Pro a WD Red Plus umí a jaké jsou mezi nimi rozdíly.

Pokračování ...



Public Relations

3Dconnexion zve na svůj stánek na veletrhu MSV 2022

3DconnexionNavštivte stánek 3Dconnexion během Mezinárodního strojírenského veletrhu v Brně a vyzkoušejte ergonomické nástroje pro práci s CAD/CAM. Na stánku na vás čeká mj. tombola o sadu SpaceMouse Enterprise Kit2 a také atraktivní slevový poukaz v hodnotě 20 % na nákup v e-shopu! Specialisté 3Dconnexion se na vás těší v pavilonu P na stánku 015 ve dnech 4.–7. 10. 2022.

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 »