Newsgroup: it.comp.lang.c++
Titolo: c++ e c#

Sto avvicinandomi adesso al mondo del c++
qualcuno potrebbe chiarirmi che differenza c'e' tra
il c++ e il c# ?
Il  c# e' l'evoluzione del primo ?

 Il  c# e' l'evoluzione del primo ?
http://it.wikipedia.org/wiki/Linguaggio_C_Sharp
Comunque l'ultima frase di questa parte č falsa:
<<Gli oggetti dinamici non vengono deallocati esplicitamente; la loro 
rimozione viene gestita automaticamente (implicitamente) dal 
"garbage-collector" quando non esistono piů riferimenti a tali oggetti. 
Questa gestione evita i due problemi ben noti dei dangling pointer e del 
memory leak.>>
Kiuhnm

 
Perchč?

 Perchč?
Il GC non reclama le aree di memoria (1) non piů utilizzate, ma le aree 
di memoria (2) non piů accessibili al programma. E' chiaro che (2) 
implica (1), ma non č vero il viceversa.
http://it.wikipedia.org/wiki/Memory_leak#Problemi_di_programmazione
Kiuhnm


D'accordo, allora biosgna intendersi sul signficato di memory leak.
Se un'area di memoria č non piů utilizzata, ma č ancora accessibile, 
significa che č comunque utilizzabile. Non credo che questo sia un 
memory leak.
BB

 memory leak.
Puoi decidere di non chiamarlo memory leak, ma resta memoria occupata
inutilmente.
Ciao,
Nicola


Forse non ho capito bene....
ma se ho un riferimento raggiungibile dal programma, che però non viene 
usato, sono d'accordo anche io che è memoria occupata inutilmente.
E' come se in c++ allocassi un'area di memoria senza poi usarla.
Lo chiamerei "spreco" di memoria (e credo che in realtà sia presente in 
molti programmi anche ben fatti in c++).
Detto questo, non riesco a trovare esempi di codice c# managed, che 
generino memory leak.
BB

 molti programmi anche ben fatti in c++).
Certamente, ma l'effetto e' lo stesso di un memory leak. La memoria
occupata aumenta indebitamente. Di C# non so pressoche' niente, ma per
esempio in Java e' comune usare framework che richiedono callback, o
meglio interfacce. Questo vuol dire passare istanze al framework che le
tiene in vita anche quando non servono piu'.
Ciao,
Nicola

Il  c# e' l'evoluzione del primo ?
sono 2 linguagi completamente differenti. il c++ è stato sviluppato da
un comitato apposito, il c# dalla microsoft, ke poi ha chiesto e
ottenuto la standardizzazione ufficiale. Il c# è un pò l'unione di
alcune feature del java (ereditarietà singola) e del c++ (puntatori,
solo in blocchi marchati come unsafe)

 generino memory leak.
Sul memory leak la penso come te;
In C# puoi generare memory leak tramite l'uso dei delegate e la
sottoscrizione agli eventi di un oggetto;
supponi di avere un oggetto A con lifetime pari a quello del programma
ed un oggetto B che ha una vita molto più breve (ad esempio un dialogo
utente).
Se un oggetto B (che viene istanziato ogni volta) è in ascolto su
eventi di A e alla sua _chiusura_ (Close() o simili) non si
de-sottoscrive agli eventi di A, tale sottoscrizione tiene in vita
l'oggetto B anche dopo che esso non viene più usato.
Il C# non ha modo di capire che B non ha più bisogno di eventi di A,
piano piano l'oggetto B (e tutto ciò che si porta dietro, a meno di
corrette deinizializzazioni) risale gli heap fino al terzo e li rimane
finchè è in vita il programma.
OttoDisc

 finchè è in vita il programma.
Non conosco C#, ma direi che se riaprendo il dialogo di tipo B viene 
riutilizzato l'oggetto creato in precedenza e che non e' mai stato 
cancellato, non si puo' parlare di memory leak, ma solo di un certo 
spreco di memoria.
Si puo' parlare di memory leak solo se ogni volta che si apre quel 
dialogo viene allocato un oggetto diverso, in modo che la memoria 
allocata continua ad aumentare indefinitamente aprendo e chiudendo 
ripetutamente il dialogo. Tale comportamento e' deleterio non solo 
perche' i requisiti di memoria sono illimitati, ma anche perche' la 
lista dei sottoscrittori cresce indefinitamente, con conseguente degrado 
delle prestazioni.
In tal caso, direi che e' il meccanismo di sottoscrizione a essere non 
sufficientemente robusto.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 ripetutamente il dialogo.
Si ha un memory leak quando memoria non piů utilizzabile viene vista 
dall'allocatore come utilizzabile e non č possibile correggere il problema.
Il "leak" non deve per forza venire reiterato, a voler essere pignoli.
Kiuhnm

 dall'allocatore come utilizzabile e non č possibile correggere il problema.
Com'č possibile una cosa del genere in un allocatore non buggato? Io mi trovo 
piů a mio agio con la definizione di Carlo.
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
 


Intendevo:
- Il memory leak (definizione generale) ha a che fare con aree di
memoria allocate e non più deallocabili a causa di errori logici nel
flusso di controllo del codice. Se voglio allocare un mega di roba e
non la dealloco più anche quando non è più necessaria, e se *non*
perdo la possibilità di deallocarla non produco memory leak - produco
solo del pessimo codice
- In C# possono verificarsi memory leak agendo su costrutti esterni a
quelli di allocazione/dispose.
Riguardo al resto (dialogo "B", eventi, ecc..), la discussione ci
porterebbe lontano e richiederebbe dissertare su C#, .NET e Windows, ma
qui mi pare si parli solo di C++.
Otto Disc

 Com'è possibile una cosa del genere in un allocatore non buggato?
new int;
Kiuhnm

 new int;
Se per "allocatore", in questo pezzo di thread si intende quello
managed - si parlava di C#, e allora la corretta sintassi sarebbe new
int(); - questo caso non genera memory leak.
Per il C++, è invece ovviamente un memory leak.
Otto Disc

 Per il C++, è invece ovviamente un memory leak.
Si parlava di definizioni.
Avrei anche potuto scrivere l'esempio in Pascal.
I memory leak sono conosciuti per i loro effetti e sono quindi temuti. 
Questo non significa che tali effetti possano essere eliminati evitando 
i memory leak. I memory leak sono solo una delle tante cause. Purtroppo 
il garbage collector non elimina gli sprechi di memoria. La memoria è 
sempre potenzialmente recuperabile (quindi non vi sono leak) però di 
fatto gli effetti sono gli stessi (out-of-memory, per es.).
Kiuhnm

 new int;
A me sembra che questo esempio rientri nella definizione di Carlo. La tua 
aggiunge forse casi con contemplati da quella?


 aggiunge forse casi con contemplati da quella?
int i = 0;
void f()
{
   if (!i)
   {
     new int;
     ++i;
   }
}
Kiuhnm

 }
Non capisco dove vuoi arrivare. A me sembra che il tuo esempio mostri un 
resource leak voluto, niente di piů.


 resource leak voluto, niente di piů.
Ti ho presentato un caso non contemplato dalla sua def. Cosa vuoi di piů???
Kiuhnm

 Ti ho presentato un caso non contemplato dalla sua def. Cosa vuoi di piů???
Ok, mi sono riletto il thread ed effettivamente mi era sfuggito il punto sulla 
reiterazione, o meglio non gli avevo dato importanza dato che una o cento 
iterazioni non mi pare facciano alcuna differenza. Se non rilascio la memoria 
allocata quando non mi serve piů c'č resource leak, specialmente se ne perdo 
il riferimento. Convengo che la definizione "non mi serve piů" non č molto 
precisa ma non puň giustificare esempi come il tuo.


 il riferimento.
No, *solo* se ne perdi il riferimento.
Gli altri non sono propriamente leak, ma soltanto sprechi.
"leak" significa "crepa", "fenditura", "perdita", "fuoriuscita".
In ogni caso è molto difficile stabilire, in generale, se del codice 
spreca memoria.
Kiuhnm

 memoria.
Se lo "spreco" è voluto dal programmatore allora lui sa a cosa gli serve 
quella memoria. Altrimenti è leak, non si scappa. Almeno io la vedo così, 
soprattutto per esperienza.



D'accordo. Tuttavia un memory leak diventa un problema solo quando e' 
reiterabile.
E' un discorso analogo al problema dell'ossidazione dei metalli. Il 
ferro e l'alluminio si ossidano a contatto con l'aria? A rigore si 
ossidano entrambi. Tuttavia, l'ossido di alluminio aderisce strettamente 
al metallo e ne impedisce ulteriori ossidazioni, mentre l'ossido di 
ferro si sfalda e l'ossidazione procede. Quindi, da un punto di vista 
metallurgico, il ferro si ossida e l'alluminio no.
Se chiamando una libreria ho la certezza che viene allocata memoria solo 
alla prima chiamata, sono soddisfatto; se invece viene allocata memoria 
ad ogni chiamata, ho un problema. Se la memoria allocata alla prima 
chiamata non e' piu' accessibile, si tratta di un memory leak, che non 
costituisce un grosso problema.
Nel caso del C#, il garbage collector garantisce che non ci siano memory 
leak a livello di allocazione di memoria. Tuttavia, puň esserci una 
libreria che, se utilizzata non rispettando un preciso protocollo (crea, 
usa, distruggi), alloca memoria ad ogni chiamata e non rende disponibile 
tale memoria al programma chiamante. Tale memoria e' accessibile alla 
libreria, in quanto referenziata da puntatori memorizzati in una lista 
interna alla libreria, e quindi non puo' essere reclamata dal garbage 
collector.
Dal punto di vista del programma chiamante, senza voler entrare nei 
dettagli interni della libreria, tale libreria sembra avere un memory 
leak, in quanto ha allocato della memoria che non e' piu' utilizzabile 
dal programma applicativo e non verra' utilizzata nemmeno dalla 
libreria, anche se sappiamo che tale memoria e' teoricamente accessibile 
al codice della libreria, e quindi non si tratta di un memory leak.
Pertanto, abbiamo due fatti: il "memory leak" e l'"allocazione 
ripetibile di memoria inaccessibile al programma applicativo". Il primo 
fatto spesso, ma non sempre, produce il secondo fatto, e a volte il 
secondo fatto si produce senza che intervenga il primo.
In pratica, il primo fatto ("memory leak") e' indice di programmazione 
disordinata, ma non e' necessariamente un grosso difetto del software, 
mentre il secondo fatto ("allocazione ...") e' sicuramente un grosso 
difetto del software.


 reiterabile.
Non sono d'accordo. Un singolo leak di 500 MB è ugualmente problematico.
Qualche giorno fa ho avuto qualche difficoltà a trovare un errore di 
allocazione finché non ho chiesto al mio MemMon di determinare la 
chiamata che allocava più memoria in una volta sola: non avendo azzerato 
una variabile "size" quando necessario, la chiamata alla new allocava 
sempre più memoria in quanto size veniva incrementato di continuo. Dopo 
10 minuti venivano allocati ben 2 GB. Questo non è nemmeno un leak 
eppure è un grosso problema.
Kiuhnm

 Non sono d'accordo. Un singolo leak di 500 MB è ugualmente problematico.
Gli sprechi di memoria non ripetibili (dovuti a memory leak oppure no) 
possono essere piccoli (meno di un centesimo della memoria complessiva 
dell'applicazione) o grandi.
Quelli piccoli non creano grossi inconvenienti.
Quelli grandi sono un difetto che viene subito diagnosticato dal 
programmatore stesso.
I difetti piu' costosi sono quelli diagnosticati tardi, cioe' quando il 
software e' gia' in fase di collaudo o addirittura di produzione.
Inoltre, in fase di debugging, una singola allocazione molto piu' grande 
del dovuto e' facilmente individuabile, mentre un numero eccessivo di 
allocazioni o un numero insufficiente di deallocazioni e' piu' difficile 
da analizzare.


 da analizzare.
Non direi. L'allocazione troppo grande deve essere di molto più grande 
per saltare all'occhio, mentre i leak, seppur piccolissimi, 
s'individuano immediatamente e infallibilmente. Non esiste un metodo 
automatico per determinare allocazioni troppo grandi.
Kiuhnm

 automatico per determinare allocazioni troppo grandi.
Non mi sono spiegato bene.
Non intendevo confrontare i memory leak con gli sprechi di memoria, ma 
gli sprechi isolati con quelli ripetuti, per sostenere che gli sprechi 
ripetuti sono piu' dannosi di quelli isolati.
Se il programma spreca un blocco di 500 MB, me ne accorgo subito; se 
invece spreca 10 KB al secondo, potrei non accorgermene io, ma se ne 
accorgerebbe chi usa il programma per piu' di 24 ore consecutive.
Se poi lo spreco consiste in un memory leak, e uso una tecnica per 
rilevare i memory leak, allora me ne accorgerei anch'io.


 rilevare i memory leak, allora me ne accorgerei anch'io.
Dipende dopo quanto tempo spreca 500 MB.
Ti contesto solo l'affermazione secondo la quale un memory leak sia 
problematico soltanto se reiterabile. Per me non è vero.
Immagina di avere un programma che ogni 20 ore generi un memory leak di 
500 MB.
Kiuhnm

 500 MB.
Non che "ogni 20 ore", ma che "in media dopo 20 ore"... (una sola volta 
insomma).
Kiuhnm