Funzione che richiama se stessa

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
Absolut
Linux 3.x
Linux 3.x
Messaggi: 1465
Iscritto il: gio feb 10, 2005 0:00
Slackware: current
Località: Roma

Funzione che richiama se stessa

Messaggioda Absolut » sab set 12, 2009 8:28

Salve ragazzi, ho un piccolo quesito:
sto leggendo un codice in c++ e.....

1) ho una funzione void pippo(bla bla bla)
dentro a questa vengono fatte delle operazioni e vengono definite due variabili:

Codice: Seleziona tutto

   int* Edges_First_hop = nNodeList[ID(sNode)].nNeighbours;
        bool* Edges_Label = new bool [nNumEdges];


2) se alcune cose sono rispettate, la funzione si richiama


Ora, dovendo pulire la memoria, se io alla fine della funzione faccio

Codice: Seleziona tutto

delete Edge_First_hop;
delete Edges_Label;



3) quelle due varibili dovrebbero essere locali giusto!? nel senso che
in pippo() chiamata la prima volta vengono create,
in pippo chiamata dentro pippo vengono nuovamente create, ma dovrebbero essere distinte dalle quelle di prima giusto!? quindi posso farci il delete!?

grazie!

Avatar utente
Vito
Staff
Staff
Messaggi: 4175
Iscritto il: mar dic 05, 2006 17:28
Nome Cognome: Vito
Distribuzione: Linux Mint 17
Località: Augsburg (DE)
Contatta:

Re: Funzione che richiama se stessa

Messaggioda Vito » sab set 12, 2009 9:20

Puoi fare sì il delete..
ma perchè le elimini?Devi riallocarle?
"Stat rosa pristina nomina, nomina nuda tenemus." [ Umberto Eco - Il nome della rosa]

"Faber est suae quisque fortunae ." [ Appio Claudio Cieco]

Avatar utente
lamarozzo
Linux 2.6
Linux 2.6
Messaggi: 732
Iscritto il: gio lug 14, 2005 0:00
Desktop: xfce
Distribuzione: archlinux
Località: Roma

Re: Funzione che richiama se stessa

Messaggioda lamarozzo » sab set 12, 2009 10:10

Le variabili locali vanno deallocate con delete ogni volta che la funzione sta per uscire e cedere il controllo alla funzione che l'ha chiamata. Questo perchè sono variabili locali e quando esci dalla funzione perdi il puntatore alle aree di memoria, che quindi non puoi più deallocare, e hai memory leak. Non penso che questa strategia sia buona per delle funzioni ricorsive, sarebbe meglio allocare la memoria alla prima chiamata e poi farla usare da tutte le funzioni, passando i puntatori tramite l'interfaccia della funzione.

Avatar utente
Vito
Staff
Staff
Messaggi: 4175
Iscritto il: mar dic 05, 2006 17:28
Nome Cognome: Vito
Distribuzione: Linux Mint 17
Località: Augsburg (DE)
Contatta:

Re: Funzione che richiama se stessa

Messaggioda Vito » sab set 12, 2009 10:12

Ecco , non mi ricordavo questo...
Troppo tempo a non programmare fa male :roll: :roll:
"Stat rosa pristina nomina, nomina nuda tenemus." [ Umberto Eco - Il nome della rosa]

"Faber est suae quisque fortunae ." [ Appio Claudio Cieco]

Avatar utente
Absolut
Linux 3.x
Linux 3.x
Messaggi: 1465
Iscritto il: gio feb 10, 2005 0:00
Slackware: current
Località: Roma

Re: Funzione che richiama se stessa

Messaggioda Absolut » sab set 12, 2009 13:02

Il problema è che se dovessi allocare la memoria tutt aprima non basterebboero vari GByte!!!

comunque... perchè non dovrebbero andare bene per funioni ricorsive!?

Pippo() crea la variabile A
e poi dentro pippo chiamo Pippo()

il nuvo Pippo() crea una varibe A
che è diversa dalla variabile A del primo pippo

Quando finisce il prio Pippo, posso fare delete A alla fine del primo Pippo() no!?

quella della seconda funzione rimane ancora valida!?

almeno andando a logica...

Avatar utente
lamarozzo
Linux 2.6
Linux 2.6
Messaggi: 732
Iscritto il: gio lug 14, 2005 0:00
Desktop: xfce
Distribuzione: archlinux
Località: Roma

Re: Funzione che richiama se stessa

Messaggioda lamarozzo » sab set 12, 2009 13:15

Absolut ha scritto:Il problema è che se dovessi allocare la memoria tutt aprima non basterebboero vari GByte!!!

Se il tuo programma usa cosi' tanta memoria rischi di esaurirla se la funzione ricorsiva viene chiamata troppo spesso. Il mio suggerimento era solo quello di riutilizzare
l'area di memoria che allochi la prima volta che chiami la funzione. Questo perche' comunque fai un delete ad ogni uscita di funzione e quindi immagino che quell'area
di memoria ti serva solo temporaneamente per lo svolgimento della funzione e non al di fuori di essa. Ma se hai bisogno di tenere copia di tutta la struttura dati
allora come hai fatto tu mi sembra giusto.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6369
Iscritto il: gio nov 03, 2005 14:05
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Funzione che richiama se stessa

Messaggioda targzeta » sab set 12, 2009 15:42

Absolut, il consiglio di lamarozzo era quello (secondo me giusto) di riutilizzare la memoria dell'oggetto allocato, non di allocare tutta la memoria possibile :). Se è come penso io, il consiglio era quello di fare qualcosa tipo:

Codice: Seleziona tutto

main()
{
  int* Edges_First_hop = nNodeList[ID(sNode)].nNeighbours;
  bool* Edges_Label = new bool [nNumEdges];
  ....
  pippo (Edges_First_hop, Edges_Label);
  ....
}

function pippo(int* Edges_First_hop, bool *Edges_Label)
{
  ...
  pippo(Edges_First_hop, Edges_Label);
}
In questo modo hai solo due oggetti allocati che però riutilizzi tutte le volte che ti richiami.

Un altra cosa, se non intendi fare in questo modo, ricorda che ci sono due possibili scenari nelle funzioni ricorsive. Il primo è quello in cui le variabili locali non ti servono più una volta eseguita la ricorsione, del tipo

Codice: Seleziona tutto

pippo()
{
  ...
  return pippo();
}
In questo caso la delete va, ovviamente, fatta prima della ricorsione.
Un altro scenario, più raro e meno consigliato, e quello in cui la funzione usa il risultato della sua ricorsione, tipo:

Codice: Seleziona tutto

pipp
{
  ...
  a=pippo();
  fai_qualcosa_con_a;
  return x;
}
in questo caso, ovviamente la delete va fatta prima del return.

Il tutto per dire, occhio a come usi la ricorsione, nel secondo caso, tutta la memoria rimane allocata sino a che la ricorsione non finisce, solo quando l'ultima funzione ricorsiva termina, iniziano le delete a cascata.

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà 


Torna a “Programmazione”

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti