Repository 32bit  Forum
Repository 64bit  Wiki

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.

Funzione che richiama se stessa

Messaggioda Absolut » sab set 12, 2009 7: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
Absolut
Linux 3.x
Linux 3.x
 
Messaggi: 1465
Iscritto il: gio feb 10, 2005 0:00
Località: Roma
Slackware: current

Re: Funzione che richiama se stessa

Messaggioda Vito » sab set 12, 2009 8: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
Vito
Staff
Staff
 
Messaggi: 4132
Iscritto il: mar dic 05, 2006 17:28
Località: Augsburg
Nome Cognome: Vito
Slackware: 64 14.0 multilib
Kernel: 3.2.29-xps
Desktop: KDE 4.10.2
Distribuzione: Linux Mint 17

Re: Funzione che richiama se stessa

Messaggioda lamarozzo » sab set 12, 2009 9: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
lamarozzo
Linux 2.6
Linux 2.6
 
Messaggi: 732
Iscritto il: mer lug 13, 2005 23:00
Località: Roma
Desktop: xfce
Distribuzione: archlinux

Re: Funzione che richiama se stessa

Messaggioda Vito » sab set 12, 2009 9: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
Vito
Staff
Staff
 
Messaggi: 4132
Iscritto il: mar dic 05, 2006 17:28
Località: Augsburg
Nome Cognome: Vito
Slackware: 64 14.0 multilib
Kernel: 3.2.29-xps
Desktop: KDE 4.10.2
Distribuzione: Linux Mint 17

Re: Funzione che richiama se stessa

Messaggioda Absolut » sab set 12, 2009 12: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
Absolut
Linux 3.x
Linux 3.x
 
Messaggi: 1465
Iscritto il: gio feb 10, 2005 0:00
Località: Roma
Slackware: current

Re: Funzione che richiama se stessa

Messaggioda lamarozzo » sab set 12, 2009 12: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
lamarozzo
Linux 2.6
Linux 2.6
 
Messaggi: 732
Iscritto il: mer lug 13, 2005 23:00
Località: Roma
Desktop: xfce
Distribuzione: archlinux

Re: Funzione che richiama se stessa

Messaggioda targzeta » sab set 12, 2009 14: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à
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6163
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti

cron