Newsgroup: it.comp.lang.c++
Titolo: Delucidazioni puntatori

Salve a tutti,
non mi è chiara bene l'allocazione della memoria con i puntatori. Mi 
spiego con un esempio:
char* funzione(int n){
       char* ret = (char*)malloc(2);
       n %= 10;
       ret[0] = '0'+n;
       ret[1] = 0;
       return ret;
}
int main(){
     char* a;
     a = funzione(1);
     a = funzione(2);
}
Una volta che viene chiamata funzione(1) la memoria viene allocata con 
malloc e quindi se io volessi liberare la memoria dovrei chiamare free.
Ma se io cambio il riferimento chiamando nuovamente funzione(2) la 
memoria allocata da funzione(1) rimane allocata e non c'è modo di 
liberarla, giusto?

 liberarla, giusto?
Giusto.
Max

 Max
Grazie per la risposta,
ma a questo punto io come faccio a sapere se cio che mi restituisce una 
funzione deve essere liberato o meno? E come faccio a sapere se devo 
utilizzare free o delete?
Questo mi sembra un bel problema perchè dovrebbe essere difficile 
individuarlo.

 individuarlo.
Infatti proprio per questo conviene che chi alloca la memoria abbia anche la
responsabilità di rilasciarla. Quindi meglio scrivere funzioni che lavorano su
buffer preallocati se devono restituirne il puntatore. In una parola, che sia
chiara la "ownership" del puntatore stesso.
In alternativa si possono utilizzare gli smart pointer, oggetti che detengono
la ownership della memoria che allocano e la rilasciano automaticamente al
termine del loro "ciclo vitale".
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic

Grazie a tutti per le risposte

 Grazie a tutti per le risposte
voglio aggiungere un consiglio anche se magari ormai non ti 
serve più : il concetto di classe, anche solo come container di 
memoria, ti può essere molto utile per gestire dietro le quinte 
allocazione e disallocazione
nel costruttore esegui NEW (meglio di malloc)
nel distruttore esegui DELETE [] (meglio di free).
Scritta al classe smetti di preoccuparti (eccetto magari qualche 
eccezione se la memoria non si trova. In ogni caso il 
costruttore del buffer ti assicura che, se torna, la memoria è 
valida, se non trova risorse, lancia un'eccezione per cui non ti 
ritrovi mai un puntatore che sembra valido e non è). Anche per 
il recupero risorse è uan strada sicura perché libera il buffer 
solo quando la reference all'istanza che la possiede esce di scope.
ciao
CCCP++Mario

 buffer preallocati se devono restituirne il puntatore. 
Si, anche se questo ovviamente va bene fino a che si parla di
programmazione single threaded.
Il C++ ovviamente non sa cosa sia un thread, ma questa non e' una scusa
valida, in quanto la maggior parte dei prodotti C++ in commercio
utilizzano i threads.
Tommaso Galleri
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Soviet_Mario ha scritto:

Grazie per la risposta,
a dire la verità ci avevo pensato ad uscirmene con delle classi ben 
progettate. Il problema si manifesta soltanto se intendo modificare 
qualche software open source.
Grazie di nuovo
Ciao

 utilizzano i threads.
Non è una scusa.


 programmazione single threaded.
Penso che Enrico parlasse di buffer allocati *dal chiamante*, dato che
parlava di "ownership".
Tu, invece, ti riferivi, evidentemente, all'uso di strutture con lifetime
statico, pratica che in generale va senz'altro evitata.
Max

 statico, pratica che in generale va senz'altro evitata.
Ah, certo, d'accordissimo!


 servono.
No, certo, ma tutto va utilizzato quando serve e con le opportune cautele. E
per gli oggetti statici o globali ce ne vogliono veramente tante... :-)


 senza una qualche cosa di statico ?
Nessun accrocchio. Al momento della loro creazione i thread ricevono un
riferimento alle strutture condivise su cui dovranno avere visibilità. Tali
strutture hanno il lifetime più appropriato e non richiedono l'ausilio di
variabili globali.
Max

 Max

 qualche software open source.
Beh, di  solito sono progettati a modo. Non tutti, ovvio. Ma
complessivamente si.
-- 
Odio gli indifferenti, perche` mi da noia il loro 
piagnisteo di eterni innocenti. [...]
Sono Partigiano. Percio` odio chi non parteggia.
Odio gli indifferenti. (Gramsci)

 invece non mi danno. (ma questa paranoia è un'altra storia)
Secondo me non ci si sta capendo sul significato di "static".


 problema della reentrance ?
Se lavori con piů thread e hai un oggetto statico nella memoria, devi
essere sicuro che le funzioni che ci lavorano sopra non si incasinino
vicendevolmtente, per dirla breve.


 vicendevolmtente, per dirla breve.
Giusto. Attenzione però confondere "thread-safety" con "reentrance".
Una funzione può essere 'thread-safe' senza essere 'reentrant', e può essere
'reentrant' senza essere 'thread-safe'.
Max

 Giusto. Attenzione però confondere "thread-safety" con "reentrance".
Of course. Ma quando penso ad oggetti statici generalmente penso prima
alla reentraza. ;) 


 
che sarebbe?
-- 
Devaraja (Xdevaraja87^gmail^c0mX)
Linux Registerd User #338167
http://counter.li.org

 che sarebbe?
http://en.wikipedia.org/wiki/Reentrant
la thread safety invece è quiesta:
http://en.wikipedia.org/wiki/Thread-safe


 quindi passo e chiudo
OK.


 quindi passo e chiudo
OK.
