Torna indietro   Hardware Upgrade Forum > Software > Programmazione

DJI Lito 1 e Lito X1 recensione: i nuovi droni per principianti che non si fanno mancare nulla
DJI Lito 1 e Lito X1 recensione: i nuovi droni per principianti che non si fanno mancare nulla
DJI ha appena ufficializzato la serie Lito, la sua nuova gamma di droni entry-level destinata a chi si avvicina per la prima volta alla fotografia aerea. Al centro dell'annuncio ci sono due modelli ben distinti per fascia di prezzo e specifiche tecniche: DJI Lito 1 e DJI Lito X1. Entrambi si collocano sotto la soglia regolamentare dei 249 grammi, che permette di volare con requisiti burocratici più semplici rispetto ai droni più pesanti.
Sony World Photography Awards 2026: i premiati, anche italiani, il punto sulla fotografia di oggi
Sony World Photography Awards 2026: i premiati, anche italiani, il punto sulla fotografia di oggi
Siamo stati a Londra per la premiazione dei Sony World Photography Awards 2026, l'evento a tema fotografia più prestigioso. Fra sorprese e novità, ne approfittiamo per fare il punto sulla fotografia contemporanea, in cui la didascalia è sempre più necessaria a cogliere il senso della quasi totalità degli scatti.
Una settimana con Hyundai Ioniq 5 N-Line: diverte e convince
Una settimana con Hyundai Ioniq 5 N-Line: diverte e convince
L'elettrica di casa Hyundai propone una versione AWD con estetica derivata dalla famiglia N. L'abbiamo provata per diversi giorni, per scoprire tutti i dettagli e la vera autonomia in autostrada
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-05-2021, 10:19   #1
tuvok01
Junior Member
 
Iscritto dal: May 2021
Messaggi: 1
C++ gestione memoria

Ciao a tutti.

Ho un dubbio che probabilmente è banale.
Allora io ho un processo che, in base ad un evento chiama un metodo di una classe. Il metodo è simile a questo, crea un messagio e lo invia sulla rete:

Codice:
void Manager::doOp() {
    for(int i=0; i <=10; i++) {
        Message* msg = new Message();
        send(msg);
    }
}
Questa parte di codice ogni volta che è chiamata porta ad un memory leak giusto? Per risolverlo dovrebbe bastare mettere una "delete msg" subito dopo la send credo.
Ma nel momento in cui il processo che possedeva l'istanza della classe manager viene terminato, e ne viene poi creato uno nuovo senza terminare il programma. La parte di memoria occupata dai messaggi creati viene liberata?

Grazie.
tuvok01 è offline   Rispondi citando il messaggio o parte di esso
Old 10-05-2021, 11:50   #2
-MiStO-
Senior Member
 
Iscritto dal: May 2005
Città: Trieste
Messaggi: 2287
ciao

senza sapere cosa fa esattamente il metodo send si può solo ipotizzare(magari questo metodo è delegato al cleanup dopo l'effettiva spedizione...), comunque sì, in linea di massima c'è un memleak e va risolto o con una delete oppure, scelta migliore usando smart pointer che semplificano enormemente la vita in operazioni di questo tipo

solitamente la memoria heap è "per-process", quindi viene rilasciata alla chiusura del processo
__________________
neo mini v2 / asus strix z490i / 10600k@? / uh12s / rx6700xt / 32gb ddr4@3200 / sandisk 250 + asenno 1tb / lenovo g34w
trattative concluse : tante...

-MiStO- è offline   Rispondi citando il messaggio o parte di esso
Old 18-05-2021, 07:47   #3
jepessen
Senior Member
 
L'Avatar di jepessen
 
Iscritto dal: Jul 2007
Città: Sicilia
Messaggi: 6669
Il principio di buona programmazione prevede che la classe che crea un puntatore ne diventa l'owner, quindi dovrebbe essere responsabile anche della sua cancellazione. Quindi una classe/funzione che accetta un puntatore come argomento non dovrebbe cancellarla. Questo principio evita problemi come utilizzo di dangling pointer o memory leak, perche' ogni utilizzatore del puntatore ha la sua responsabilita'.

Se per motivi di design si DEVE spostare l'ownership di un puntatore (ad esempio perche' viene creato da una factory), sarebbe opportuno dirlo esplicitamente, ad esempio con l'utilizzo di un unique_ptr che non puo' essere copiato ma soltanto spostato, quindi passarlo ad una funzione o ad una classe significa esplicitamente che lei ne acquisisce la proprieta' e ne diventa responsabile.

Quindi nel tuo caso "send()" non dovrebbe cancellare il puntatore, ma dovrebbe farlo il tuo manager nel ciclo. Se dovesse per qualche motivo cancellarlo il "send()" allora invece di "Message*" dovresti fare un "std::unique_ptr<Message>" e passarlo per move al send. In questo modo si invalida il puntatore del ciclo for dato che viene "mosso" e non "copiato" all'interno del send, la cui signature diventa "void send(std::unique_ptr<Message>&& message", e quando finira' il suo scope verra' automaticamente cancellato.
__________________
Non abbiamo ereditato il mondo dai nostri padri
L'abbiamo preso in prestito dai nostri figli

Ultima modifica di jepessen : 18-05-2021 alle 07:49.
jepessen è offline   Rispondi citando il messaggio o parte di esso
Old 27-06-2021, 11:42   #4
DanieleC88
Senior Member
 
L'Avatar di DanieleC88
 
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
Scusa l'ignoranza, ma se send() non prende possesso di quella memoria, a che serve allocarla sullo heap?

Non ti basta fare questo?

Codice:
void Manager::doOp() {
    for(int i=0; i <=10; i++) {
        Message msg;
        send(&msg);
    }
}
__________________

C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai!
DanieleC88 è offline   Rispondi citando il messaggio o parte di esso
Old 28-06-2021, 20:52   #5
Lampo89
Member
 
L'Avatar di Lampo89
 
Iscritto dal: Dec 2006
Messaggi: 33
Quote:
Originariamente inviato da DanieleC88 Guarda i messaggi
Scusa l'ignoranza, ma se send() non prende possesso di quella memoria, a che serve allocarla sullo heap?

Non ti basta fare questo?

Codice:
void Manager::doOp() {
    for(int i=0; i <=10; i++) {
        Message msg;
        send(&msg);
    }
}
concordo anche io con questo suggerimento, anche se con le poche informazioni a disposizioni non è detto che sia il modo più safe per risolvere il problema ( per gli stessi dubbi che hai anche tu).
Ad esempio, se la send() avvenisse in maniera asincrona il rischio è che al momento dell'invio venga letta memoria non valida (msg verrebbe cancellata alla chiusura del blocco in cui è dichiarata). In un caso del genere, deve avvenire un trasferimento di ownership della memoria.

Come detto, meglio usare unique_ptr e trasferire l'ownership alla funzione send() ma, secondo me, con le informazioni a disposizione è difficile dare una risposta più precisa ...

Ultima modifica di Lampo89 : 28-06-2021 alle 21:33.
Lampo89 è offline   Rispondi citando il messaggio o parte di esso
Old 28-06-2021, 21:17   #6
Lampo89
Member
 
L'Avatar di Lampo89
 
Iscritto dal: Dec 2006
Messaggi: 33
Quote:
Originariamente inviato da jepessen Guarda i messaggi
Quindi nel tuo caso "send()" non dovrebbe cancellare il puntatore, ma dovrebbe farlo il tuo manager nel ciclo. Se dovesse per qualche motivo cancellarlo il "send()" allora invece di "Message*" dovresti fare un "std::unique_ptr<Message>" e passarlo per move al send. In questo modo si invalida il puntatore del ciclo for dato che viene "mosso" e non "copiato" all'interno del send, la cui signature diventa "void send(std::unique_ptr<Message>&& message", e quando finira' il suo scope verra' automaticamente cancellato.
a meno dell'osservazione sopra, mi trovi d'accordo con il tuo suggerimento nel senso che è la pratica più safe per è possibile allo stato attuale della conoscenza.

Solamente, modificherei invece la signature del metodo send() in:
send(std::unique_ptr<Message> message)

in modo da eseguire esplicitamente il passaggio di ownership del puntatore alla funzione send(). Nel modo in cui proponi, passeresti comunque una referenza (una ref ad un temporaneo) ma, in assenza di ulteriori move del puntatore nel corpo della funzione, il trasferimento di ownership non avverrebbe.

questo esempio dovrebbe chiarificare, nota come dopo prima chiamata (argomento unique_ptr&&) lo smart pointer è ancora valido, mentre dopo la seconda è nullptr in seguito alla costruzione dell'argomento via move constructor

https://gist.github.com/Lampo89/8194...ec47777ba3454c

Non c'entra nulla, ma giro un link su best practices riguardo la gestione della memoria (il link punta al caso che facevo notare). ci sono molti altri suggerimenti interessanti che vale davvero la pena leggere, opinione mia
http://isocpp.github.io/CppCoreGuide...ip-of-a-widget

Ultima modifica di Lampo89 : 28-06-2021 alle 22:02.
Lampo89 è offline   Rispondi citando il messaggio o parte di esso
Old 29-06-2021, 09:09   #7
jepessen
Senior Member
 
L'Avatar di jepessen
 
Iscritto dal: Jul 2007
Città: Sicilia
Messaggi: 6669
Quote:
Originariamente inviato da Lampo89 Guarda i messaggi
a meno dell'osservazione sopra, mi trovi d'accordo con il tuo suggerimento nel senso che è la pratica più safe per è possibile allo stato attuale della conoscenza.

Solamente, modificherei invece la signature del metodo send() in:
send(std::unique_ptr<Message> message)

in modo da eseguire esplicitamente il passaggio di ownership del puntatore alla funzione send(). Nel modo in cui proponi, passeresti comunque una referenza (una ref ad un temporaneo) ma, in assenza di ulteriori move del puntatore nel corpo della funzione, il trasferimento di ownership non avverrebbe.

questo esempio dovrebbe chiarificare, nota come dopo prima chiamata (argomento unique_ptr&&) lo smart pointer è ancora valido, mentre dopo la seconda è nullptr in seguito alla costruzione dell'argomento via move constructor

https://gist.github.com/Lampo89/8194...ec47777ba3454c

Non c'entra nulla, ma giro un link su best practices riguardo la gestione della memoria (il link punta al caso che facevo notare). ci sono molti altri suggerimenti interessanti che vale davvero la pena leggere, opinione mia
http://isocpp.github.io/CppCoreGuide...ip-of-a-widget
La realta' e' che l'utilizzo dei puntatori a sproposito e' il tipico sintomo di uno sviluppatore che ha raggiunto il primo picco del grafico di Dunning-Kruger. Quando studi i puntatori e vedi la loro potenza allora sei convinto che debbano essere utilizzati ovunque, quando in realta' si tende a minimizzare il loro utilizzo, e quando vengono utilizzati si dovrebbe quanto piu' possibile limitarne lo scope (ad esempio sfruttando il RAII). Ci sono un sacco di problemi che sembrano risolvibili con i puntatori ma che in realta' non lo richiedono, senza arrivare a rompere i cabbasisi con l'utilizzo di std::variant con std::visit per mimare il polimorfismo... In genere quando fai un'applicazione dovresti avere ben chiaro dove i puntatori vengono creati e vengono distrutti, e capire quindi quando effettivamente servono e quando no. Quando servono poi, a meno di compatibilita' con librerie terze, e' sempre meglio utilizzare gli smart pointer, stanno li' per questo, e ormai risalgono al C++11, quindi non e' giustificabile ad esempio non insegnarli in un corso universitario di C++ al giorno d'oggi. E' sacrosanto insegnare i puntatori raw, come si e' sempre fatto, ma dopo occorre spiegare cosa sono gli smart pointer e come utilizzarli in maniera proficua.

Anche le CppCoreGuidelines sono veramente un'ottima lettura, ma a mio avviso il fatto di avere un unico .md rende la lettura pesante, ed anche il file. Preferisco convertirlo in PDF per poterlo leggere con piu' naturalezza, riaprire il file per ricominciare a leggere da dove avevo interrotto etc... Anche abilitare il check delle regole cpp sugli IDE come visual studio e' molto interessante, e permette di analizzare i "code smell" il prima possibile.
__________________
Non abbiamo ereditato il mondo dai nostri padri
L'abbiamo preso in prestito dai nostri figli
jepessen è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


DJI Lito 1 e Lito X1 recensione: i nuovi droni per principianti che non si fanno mancare nulla DJI Lito 1 e Lito X1 recensione: i nuovi droni p...
Sony World Photography Awards 2026: i premiati, anche italiani, il punto sulla fotografia di oggi Sony World Photography Awards 2026: i premiati, ...
Una settimana con Hyundai Ioniq 5 N-Line: diverte e convince Una settimana con Hyundai Ioniq 5 N-Line: divert...
Recensione OPPO Find X9 Ultra: è lui il cameraphone definitivo Recensione OPPO Find X9 Ultra: è lui il c...
Ecovacs Deebot X12 OmniCyclone: lava grazie a FocusJet Ecovacs Deebot X12 OmniCyclone: lava grazie a Fo...
Il telescopio spaziale Nancy Grace Roman...
iPhone Ultra, periodo di lancio conferma...
Un anno fa debuttava Clair Obscur:&...
Tutte le offerte sugli smartphone ora pi...
Tutte le offerte sui TV ora su Amazon: u...
Xbox Game Pass sarà disponibile a...
La serie HONOR 600 avrà presto un...
Mova Viax 250 in prova: il robot tagliae...
Fat e-bike per tutti: sconti Engwe, pi&u...
Google conferma l'arrivo della nuova ver...
Apple ha trovato il modo per abbassare i...
OpenAI vuole tassare l'AI per dare a tut...
MacBook Air 15'' con chip M4 a 1.199€ su...
Samsung Galaxy S25 Edge 12/512GB a 854€ ...
Super offerta sul portatile gaming Acer ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 18:54.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v