[ miki_ja @ 16.04.2009. 23:45 ] @
Desava mi se jedna cudna situacija, ili je ja barem tako dozivljavam...
Naime, jedna metoda mi vraca objekat neke liste (od vec postojece, bira odredjene elemente).

Code:

Lista Klasa::filtriraj()
{
     Lista lista;
     for (Elm* e = prvi; e; e = e->sled)
     {
          //ovde neka provera
          lista.dodaj(*(e->nesto));
     }
     return lista;
}


Kroz debag, sve izgleda dobro. Dolazi se do 'return', regularno se pravi kopija liste (postoji copy konstruktor), i onda se poziva destruktor koji brise svu dinamicki dodeljenu memoriju u listi, a zatim se iz metode vraca prazna lista??
Kroz debag sam moga da primetim da se destruktor poziva jos jednom, odmah nakon povratka iz metode, sto je ok, ali zasto se poziva pre vracanja rezultata?
[ milanche @ 17.04.2009. 09:01 ] @
Zato sto je 'Lista lista' lokalna promenljiva doticne funkcije, instancionirana na stack-u,
pa po izvrsenju funkcije izlazi iz 'vazenja' (tj. biva unistena, poziva joj se destruktor).

Moras je ili uciniti trajnijom (da bude clanica klase, naprimer) ili alocirati dinamicki pa ostaviti
obavezu funkciji koja poziva filtriraj( ) metodu da je dealocira kad ne bude vise trebala.

Ne bi bilo lose ni da funkcija koja poziva filtriraj( ) metodu sama kreira listu i prosledi njenu adresu
kao ulazni argument (Lista* pLista), tj:

Code:

// negde u funkciji koja poziva filtriraj( ) metodu:
....
Lista lista;
filtriraj(&lista);
...


Odaberi sam sta ti je najbolje resenje prema ostatku programa.
[ miki_ja @ 17.04.2009. 10:14 ] @
Ok, jasno mi je to, nego nisam bas ocekivao da se obrise pre nego sto se vrati kopija.

Uradicu po tvom trecem predlogu, tako ce sigurno raditi... hvala... pozz...
[ Goran Arandjelovic @ 17.04.2009. 11:36 ] @
Citat:
milanche: Zato sto je 'Lista lista' lokalna promenljiva doticne funkcije, instancionirana na stack-u,
pa po izvrsenju funkcije izlazi iz 'vazenja' (tj. biva unistena, poziva joj se destruktor).

Moras je ili uciniti trajnijom (da bude clanica klase, naprimer) ili alocirati dinamicki pa ostaviti
obavezu funkciji koja poziva filtriraj( ) metodu da je dealocira kad ne bude vise trebala.

Ne bi bilo lose ni da funkcija koja poziva filtriraj( ) metodu sama kreira listu i prosledi njenu adresu
kao ulazni argument (Lista* pLista), tj:

Code:

// negde u funkciji koja poziva filtriraj( ) metodu:
....
Lista lista;
filtriraj(&lista);
...


Odaberi sam sta ti je najbolje resenje prema ostatku programa.


Ali bez obzira što je "lista" lokalna, pre nego što bude uništena, ona će biti iskopirana jer ne vraća kao povratnu vrednost referencu već je vraća po vrednosti.

A ako pretpostavimo da negde u kodu ima poziv:

Code:

Klasa obj;
Lista L = obj.filtriraj();


kompajler obično ovde vrši RVO, tako da će to da "pretoči" u nešto ovako:

Code:

Klasa obj;
Lista L;
obj.filtriraj(L);


da nebi bilo jedne suvišne kopije u "return lista".

Ja bih testirao lepo konstruktor kopije, jer može da se desi da je tamo problem. (Tj. sumnjam da konstruktor kopije radi deep copy kako treba, pa možda onda neki destruktor negde nešto uništava)
[ DjoleReject @ 17.04.2009. 13:51 ] @
Citat:
Goran Arandjelovic: Ali bez obzira što je "lista" lokalna, pre nego što bude uništena, ona će biti iskopirana jer ne vraća kao povratnu vrednost referencu već je vraća po vrednosti.


Da, bez obzira na to sto je objekat lista lokalan, on se vrati po vrednosti i to ne predstavlja problem. Proveri destruktor Elm-a i destruktor Liste. Jos bolje, napisi ih ovde, pa cemo naci sta je problem.
[ milanche @ 17.04.2009. 16:33 ] @
Citat:
Ja bih testirao lepo konstruktor kopije, jer može da se desi da je tamo problem. (Tj. sumnjam da konstruktor kopije radi deep copy kako treba, pa možda onda neki destruktor negde nešto uništava)


Da, ovo je pravi uzrok problema.