Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035

    [C++] Puntatori e istruzioni new/delete

    Partendo dal presupposto che l'istruzione new altro non fa che allocare la memoria e restituire un puntatore al primo byte della stessa (quindi mi pare funzioni allo stesso modo di malloc) una domanda veloce veloce: la conseguente istruzone delete del c++ equivale a quella free del c?
    Delete funziona su qualsiasi variabile puntatore o soltanto su quelle create attraverso la new?

    In nessun manuale del C ho trovato consigli a svuotare (attraverso la free) l'heap di tutti i puntatori allocati quindi questa delete mi suona abbastanza strana, perchè la mancata deallocazione si dice porti ad un memory leak... Che mi dite?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Dico che parti da un presupposto sbagliato.

    La new (e la delete) si usano per creare (distruggere) un oggetto di una determinata classe.

    La new, oltre ad allocare la memoria usata dai dati dell'istanza, esegue anche il costruttore tramite il quale possono essere eseguite istruzioni anche complesse ...

    La delete, ovviamente, esegue il distruttore , con tutto il codice che ne consegue.

    E' quindi una cosa molto diversa dall'uso di malloc/free.

  3. #3
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    Esiste ancora un'altra possibilità per inizializzare una variabile puntatore: utilizzando l'operatore new messo a disposizione dal C++.
    Quando si scrive:

    codice:
    int x = 20;
    int* p_x = NULL;
    ......
    ......
    
    p_x = new int;
    *p_x = x;
    quello che si ottiene è un risultato apparentemente simile a quello visto negli esempi precedenti, ma in realtà abbastanza diverso.
    L'istruzione:
    codice:
    p_x = new int
    altro non fa che allocare una quantità di memoria necessaria per contenere un int (ovvero 2 byte) ed assegnare l'indirizzo del primo byte di memoria alla variabile p_x. Questo indirizzo è certamente diverso da quello in cui è contenuta la variabile x stessa, per cui in tal caso avremo in realtà due variabili intere differenti che contengono lo stesso valore.
    E' anche possibile usare l'istruzione:

    codice:
    p_x = new int(20);
    per inizializzare direttamente il valore *p_x a 20.

    Si faccia ora attenzione. Abbiamo detto che le variabili puntatore fanno riferimento alla memoria dinamica (heap). Diversamente dalla memoria statica, tutte le variabili puntatore allocate dal programmatore devono essere poi distrutte quando non servono più, per evitare i cosìdetti "memory leaks", ovvero per evitare che la memoria allocata resti tale anche dopo la terminazione del programma.
    L'istruzione del C++ che serve per distruggere una variabile puntatore è: delete.
    Nel caso dell'esempio precedente, avremmo:

    codice:
    int x = 20;
    int* p_x = NULL;
    ......
    ......
    
    p_x = new int;
    *p_x = x;
    ......
    ......
    delete p_x;
    // La variabile p_x non serve più. Possiamo deallocarla
    ......
    ......
    Per capire cosa è un memory leak, vediamo l'esempio seguente:

    codice:
    int x = 20;
    int* p_x = NULL;
    ......
    ......
    
    p_x = new int;
    p_x = & x; // Attenzione!! Memory leak!!
    *p_x = 20;
    ......
    Perchè quando si esegue l'istruzione p_x = new int si sta creando un memory leak? La risposta è semplice. La variabile p_x è stata innanzitutto inizializzata utilizzando l'istruzione p_x = new int.
    Tale istruzione ha fatto sì che venissero allocati due byte ed assegnato l'indirizzo del primo di questi byte alla variabile p_x. Quando poi si esegue l'istruzione p_x = & x la variabile p_x viene fatta puntare all'indirizzo in cui è contenuta la variabile x ma in nessun modo viene deallocata la memoria che era stata allocata in precedenza. Questo causa il famoso memory leak.
    Bisogna stare molto attenti ai memory leak. Spesso non sono semplici da riconoscere e possono causare problemi ai programmi causando una graduale diminuzione delle risorse di sistema.
    Per evitare il memory leak di prima avremmo dovuto scrivere:

    codice:
    int x = 20;
    int* p_x = NULL;
    ......
    ......
    
    p_x = new int;
    delete p_x; // Deallocazione della memoria allocata da p_x
    p_x = & x; // Corretto!
    *p_x = 20;
    ......
    L'ho letto qui: http://programmazione.html.it/guide/...ile-puntatore/

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Distinguiamo due discorsi ...

    La differenza (genericamente parlando, come hai detto nel tuo primo post, senza fare riferimento ad un tipo particolare ...) tra malloc/free e new/delete, e' appunto in quello che ti ho scritto (ma questa differenza non c'entra con i memory leak ...)

    E questo e' un discorso.

    Altra cosa e' la possibilita' di avere memory leak dovuti al cattivo uso di new/delete.
    Se tu allochi della memoria (questo vale sempre, sia nel caso di malloc sia per la new) *devi* deallocarla quando non ne hai piu' bisogno (ma questo fatto non ha a che vedere con la scelta di usare la new piuttosto che la malloc ...).

    E questa e' un'altra storia.

    A questo punto, non comprendo bene quale sia il tuo dubbio ...

  5. #5
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    in C++ (visto che non conosco le differenze che ha col C) quale è allora l'equivalente della malloc/free? vedo che nell'esempio riportato nella guida vengono utilizzate per allocare/deallocare uno spazio di memoria... tu mi dici che sono utilizzate con le classi...

    E ovviamente consigliano di deallocare la memoria ogni qualvolta non serva più... io in manuali di C questo consiglio non l'ho mai trovato...

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Un attimo ... facciamo ordine ...

    L'uso della new equivale a queste due operazioni

    1) chiamata della malloc per allocare lo spazio privato della classe

    2) chiamata del costruttore

    Naturalmente, se usi la new con un tipo di dato primitivo (un int, ad esempio), allora il secondo passo non viene eseguito e la new praticamente corrisponde alla malloc.

    L'importante e' usare sempre la coppia new/delete o malloc/free per allocare/deallocare e *mai* mischiare le funzionalita'.

    Se nei tuoi manuali non e' consigliato deallocare la memoria ogni volta non serve piu', allora ti consiglio di cambiare manuali.

  7. #7
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    Forse non ci capiamo... altro tutorial online del c++ e delle calloc, malloc e realloc non c'è traccia... si parla soltanto di new/delete per allocare memoria.

    http://www.cplusplus.com/doc/tutorial/dynamic.html

    Nemmeno si fa riferimento alle classi peraltro...

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    No ... non ci capiamo ...

    Ti avevo scritto

    Naturalmente, se usi la new con un tipo di dato primitivo (un int, ad esempio), allora il secondo passo non viene eseguito e la new praticamente corrisponde alla malloc.

    e mi sembrava chiaro ...

    La new/delete e' caratteristica del C++ ma cio' non vuol dire che la malloc/free non possa essere usata in C++ perche' C++ e' un superset di C (vedi in fondo al tutorial). Ma questo non vuol dire che siano la stessa cosa (vedi spiegazione precedente).

    Il fatto che non ci sia traccia delle classi nel tutorial non implica che tutto quello che ti ho detto sia sbagliato ... Ti avevo fatto la distinzione tra uso della new con una classe e con un dato di tipo primitivo ...

    Comunque, continuo a non capire quale sia il tuo dubbio ... mi sembra tutto abbastanza semplice e lineare ... dimmi pure dove non mi sono espresso chiaramente ...

  9. #9
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,035
    ok, ora ho capito... stavo sfogliando la guida del c++ su questo stesso sito e pensavo che la new fosse l'equivalente sostitutiva della malloc, invece è una funzione usata prevalentemente sui costruttori delle classi, ma che può svolgere lo sesso ruolo della malloc. Visto che all'inizio mi dicevi che è una cosa molto diversa non riuscivo a capire per quale motivo i tutorial la usavano per allocare memoria in C++ nello stesso modo in cui io uso la malloc in C.

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Ti dicevo che e' diversa appunto perche' non e' confrontabile uno-a-uno con la malloc in quanto fa molto altro oltre che allocare memoria ...

    Comunque, se adesso e' tutto chiaro, prova a fare qualche esercizio di test ...

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 © 2025 vBulletin Solutions, Inc. All rights reserved.