Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475

    [C++] ritornare puntatore, reference o valore?

    Ciao a tutti.

    Supponiamo di avere una funzione che deve ritornare un oggetto che occupa molta memoria.
    Ad esempio, diciamo che ritorna una string che contiene moltissimo testo.

    Ovviamente ritornarla per valore sarà molto inefficiente, quindi mi sembra che sia decisamente meglio allocarla sull'heap e restituire l'indirizzo.

    Problema: ritorno un puntatore o una reference? Quale dei due è "più C++"?
    Mi verrebbe da dire reference credo... una cosa così?

    codice:
    string& mem_hog(void)
    {
        string* result = new string();
       
        //...
        
        return (*result);
    }
    E' giusto?
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    P.S: non intendo se il codice sia giusto (ho testato che funziona, o almeno, così sembra), mi chiedo solo se sia il modo giusto di farlo.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  3. #3
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Pessima idea restituire reference a oggetti stack based. E' vero che la memoria allocata sopravvive, ma il puntatore verrà perso all'uscita e di fatto ti ritrovi con un reference non valido, non potrai deallocare e il programma esplode.
    In situazioni del genere si restituisce il puntatore.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  4. #4
    Originariamente inviato da shodan
    In situazioni del genere si restituisce il puntatore.
    In realtà si dovrebbe evitare anche la restituzione di un puntatore ad un oggetto allocato nella funzione stessa. Una variabile dovrebbe sempre "nascere" e "morire" all'interno della stessa funzione quando possibile.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Pessima idea restituire reference a oggetti stack based.
    Si, lo so, ma questo è allocato nell'heap, perciò sopravvive alla funzione.

    In realtà si dovrebbe evitare anche la restituzione di un puntatore ad un oggetto allocato nella funzione stessa.
    Si, ma se l'oggetto da restituire occupa molta memoria, restituirlo per valore è troppo costoso. Un po' come passare un argomento molto massiccio per puntatore, solo che è in uscita e non in entrata.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Tecnicamente parlando, un puntatore nasce e muore nella funzione in cui è creato. Solo che il suo valore viene copiato in una nuova variabile (sempre puntatore) fuori dalla funzione, in modo da poter gestire la memoria allocata.
    Con un reference questo non avviene.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Temo di non vedere il problema... La reference che ritorno è ad un oggetto valido.

    Quello che mi stai dicendo è che facendo così non sono più in grado di deallocare quella memoria, dico bene?
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  8. #8
    Originariamente inviato da Ippo343
    Si, ma se l'oggetto da restituire occupa molta memoria, restituirlo per valore è troppo costoso. Un po' come passare un argomento molto massiccio per puntatore, solo che è in uscita e non in entrata.
    Si, ma forse mi sono spiegato male. Non è questo il modo di programmare, uno se ne accorge quando i progetti iniziano a diventare più grandi o ti trovi a gestire dei metodi fatti da altre persone, o sei tu stesso a dover implementare qualcosa che poi verrà utilizzato da altri.

    Vuoi tornare un puntatore ad un oggetto che hai creato e "riempito" dentro quella funzione? Invece di crearlo dentro la funzione che poi ti ritorna l'indirizzo, passa alla funzione stessa il puntatore all'oggetto che può essere modificato tranquillamente all'interno della tua funzione. In questo modo non ci saranno problemi per la deallocazione, accade più spesso di quanto uno possa immaginare di dimenticarsi di deallocare un oggetto il prima possibile perchè non ci si è accorti (o se come ti dicevo prima la funzione non l'hai fatta te) non si è a conoscenza che sia stata allocata memoria, e tra migliaia di righe di codice il fatto può sfuggire.

    O si da un nome alla funzione che richiama il fatto che allochi memoria (vedi malloc) o si procede come ti ho detto, che è in ogni caso la soluzione migliore.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  9. #9
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da Ippo343
    Temo di non vedere il problema... La reference che ritorno è ad un oggetto valido.
    Quello che mi stai dicendo è che facendo così non sono più in grado di deallocare quella memoria, dico bene?
    Da una prova che ho fatto il tutto parrebbe funzionare (resterebbe da capire cosa dice lo standard in proposito: si potrebbe essere al limite dell'undefined behaviour e personamente preferisco evitare).

    Per liberare la memoria parebasti:
    codice:
    string& z = mem_hog();
    
    delete &z;
    Direi scomodo.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  10. #10
    Più che altro, in generale quando si usano i reference come tipo restituito il contratto implicito è che l'ownership di ciò a cui si riferisce il reference è di chi lo restituisce, anche solo per il fatto che è inusuale ri-ricavare un puntatore da un reference. Al di là di ciò che possa dire lo standard (che non credo proibisca la sintassi indicata da shodan), del codice scritto in quella maniera è fuorviante.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.