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

Linux E X P R E S

EDU Trainings IT školení

Příspěvky Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie

Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Radek Chalupa 9. 11. 2019, 08:20:26
Odpovědět  Odkaz 
Obávám se že je to cesta do pekel. Vracíš adresu lokální proměnné, která je po opuštění funkce neplatná. To že tam zůstane "správná" hodnota bezprostředně po zavolání funkce na věc nic nemění. Pokud si výslednou adesu uložíš a vypíšeš po několika dalších voláních, zjistíš že se hodnota na té adrese změnila. Viz příklad:

int* funkce()
{
int cislo = rand() % 10 + 1;
int* pres = &cislo;
return pres;
}

void test()
{
srand(time(nullptr));
int* vysl = funkce();
printf("%d\n", *vysl);
for (size_t i = 0; i < 5; i++)
{
printf("%d ", *funkce());
}
printf("\n%d\n", *vysl);
}

a výstup je:
7
2 8 10 7 9
9

Takže z původní 7 je tam 9, tj. výsledek posledního volání.
Tomáš Crhonek Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Tomáš Crhonek 9. 11. 2019, 11:45:36
Odpovědět  Odkaz 
Přesně tak. Navíc v odkazovaném článku deklarují tu vnitřní proměnnou jako static, což sice jednak umožňuje na ní vracet pointer, ale současně je potřeba dát si pozor na to, že tato proměnná je sdílená přes všechny běhy dané funkce.

Tj pokud by funkce měla v každém volání generovat jiná data, tak není možné použít ani static proměnnou a je nutné pokaždé vytvořit (new) nový objekt v paměti a na ten dát odkaz (a potom řešit jejich rušení).

https://www.tutorialspoint.com/cplusplus/cpp_return_pointer_from_functions.htm
Eduard Boldižár Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Eduard Boldižár 9. 11. 2019, 12:55:19
Odpovědět  Odkaz 
Ja viem čo chceš povedať a áno súhlasím, že lokálna premenná zmizne a keby som ju chcel zavolať v main funkcii, tak dostanem od kompilátora svoje. Ale mi odkazujeme na funkciu a jej návratovú hodnotu a nie na jej lokálnu premennú! Takže logicky po každom volaní funkcie sa adresa funkcie s jej návratovou funkciou zmení. Treba si uvedomiť, že aj funkcia má svoju adresu a práve s ňou celý čas pracujeme.

S adresami funkcii pracujeme napr.tu: https://www.linuxexpres.cz/software/programovanie-v-jazyku-c-pointery-ukazujuce-na-funkcie ;)
Eduard Boldižár Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Eduard Boldižár 9. 11. 2019, 13:07:38
Odpovědět  Odkaz 
Ok možno k tomu ešte niečo vysvetlím. Ak mi dáme ako return pointer1;, tak funkcia si do návratovej hodnoty skopiruje takto pointer2=pointer1 a nie štýlom pointer2=*pointer1, ako by sa mohlo zdať. Nový skopírovaný pointer je zviazaný s adresou funkcie a preto môžete ho odkazovať kdekoľvek, aj keď len raz :) pretože pri ďalšom volaní sa vykoná zasa kód a vznikne nový pointer a tak dookola :)
Eduard Boldižár Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Eduard Boldižár 9. 11. 2019, 13:23:16
Odpovědět  Odkaz 
I keď to som asi tiež domotal. :) Možno funkcia skutočne uchováva takto: premennaInt=*pointer1. Avšak vypísal som si adresy tej funkcie i jej hodnoty a pravdepodobne i s deštrukciou lokálnej premennej stále uchovava danú hodnotu, čiže asi kvôli uloženej hodnoty z pointeru do klasíckého int a potom je to už len o adrese funkcie a jej hodnote. Snáď je to tak ako som povedal, ale môžem sa i mýliť :)
Tomáš Crhonek Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Tomáš Crhonek 9. 11. 2019, 13:24:41
Odpovědět  Odkaz 
Ta funkce ale nevytváří nový paměťový prostor pro uložení té proměnné. To byste tam musel mít něco jako:


int * pint = new int;
*pint = result;
return pint;


tj vytvořit si místo pro int, získat pointer na toto místo (vrací operátor new) a na toto místo uložit výsledek vašeho výpočtu a tento pointer vrátit.

Jinak vám to bude fungovat jen náhodou, protože platnost lokálních proměnných končí po ukončení bloku a kompilátor tam může umístit jiná data.
Eduard Boldižár Re: Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Eduard Boldižár 9. 11. 2019, 13:30:11
Odpovědět  Odkaz 
Ach tak, už chápem :) vďaka, aspoň je to namet na ďalší článok.
Tomáš Crhonek Re: Re: Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Tomáš Crhonek 9. 11. 2019, 13:37:25
Odpovědět  Odkaz 
Není zač. Potom je ovšem nutné řešit rušení těchto objektů, protože takto může snadno dojít k memory leakům. Proto také existují smart pointers apod, které tuto problematiku zjednodušují.
Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
pepa_u 14. 11. 2019, 11:42:17
Odpovědět  Odkaz 
Asi by to chtelo bud v tom clanku opravit a nebo ten clanek smazat, protoze jestli se tim bude nekdo insporovat, prida si starosti....
Eduard Boldižár Re: Programovanie v jazyku C++: Pointer ako návratová hodnota funkcie
Eduard Boldižár 14. 11. 2019, 13:11:28
Odpovědět  Odkaz 
Aj keď mám v pláne túto problematiku ešte rozviesť v ďalšom článku, po vašom komentári som sa zamyslel a asi by nebolo fér pre tých, ktorí si prečítajú len tento článok a ten budúci z akéhokoľvek dôvodu nie. Takže opravil som problém s pamäťou.
EDU Trainings