Stringhe in memoria dinamica

di il
44 risposte

Stringhe in memoria dinamica

Se faccio:

char* s = new char;

e poi:

cin >> s;

da tastiera posso inserire pure più caratteri (quindi una stringa), non devo per forza inserire un solo carattere. Quindi la domanda è: si deve mettere delete o delete[]?

Grazie

44 Risposte

  • Re: Stringhe in memoria dinamica

    Aiaiai!

    Questo e' uno di quegli errori che, se sei fortunato, fanno schiantare il programna nei modi piu' strani ed incomprensobili, ma se sei sfortunato, potrebbe pure funzionare.

    1) new va con delete e new[] con delete[]
    2) ci sono certe situazioni molto particolari in cui puoi mischiare i due tipi di operatori, e funziona per c.../fortuna

    3) quanto spazio (byte) hai allocato in s?
  • Re: Stringhe in memoria dinamica

    migliorabile ha scritto:


    Aiaiai!

    Questo e' uno di quegli errori che, se sei fortunato, fanno schiantare il programna nei modi piu' strani ed incomprensobili, ma se sei sfortunato, potrebbe pure funzionare.

    1) new va con delete e new[] con delete[]
    2) ci sono certe situazioni molto particolari in cui puoi mischiare i due tipi di operatori, e funziona per c.../fortuna

    3) quanto spazio (byte) hai allocato in s?
    Ancora non ho allocato niente, devo ancora provare. Ma è una domanda che mi è venuta studiando le stringhe. Quindi se ho capito bene, al di là se funzioni o meno in un modo o nell'altro mi devo regolare in questo modo:
    - se ho fatto new faccio delete
    - se ho fatto new[] faccio delete[]
    questo indipendentemente da quanti caratteri ho messo nell'heap a tempo di esecuzione. Giusto?
  • Re: Stringhe in memoria dinamica

    La regola è:
    per ogni chiamata a new corrisponde una a delete
    se hai una new avrai una delete, se hai 2137 chiamate a new avrai 2137 chiamate a delete
  • Re: Stringhe in memoria dinamica

    vbextreme ha scritto:


    la regola è:
    per ogni chiamata a new corrisponde una a delete
    se hai una new avrai una delete, se hai 2137 chiamate a new avrai 2137 chiamate a delete
    Sì ma non sto parlando di distruttori che vengono chiamati automaticamente, sono io che devo scrivere delete o delete[].
  • Re: Stringhe in memoria dinamica

    Ogni volta che scrivi new deviscrivere anche un delete.
    chiaro cosi?
  • Re: Stringhe in memoria dinamica

    vbextreme ha scritto:


    ogni volta che scrivi new deviscrivere anche un delete.
    chiaro cosi?
    Sì ma questo già lo sapevo: il fatto è che quando scrivo delete[] scrivo anche delete. Comunque, da quanto ho capito:
    new --> delete
    new[] --> delete[]
    Prendo per buona questa regola se nessuno mi smentisce.
  • Re: Stringhe in memoria dinamica

    Certo che è la regola corretta... Se usi la new[] devi usare la delete[]

    È una regola semplice...
  • Re: Stringhe in memoria dinamica

    oregon ha scritto:


    Certo che è la regola corretta... Se usi la new[] devi usare la delete[]

    È una regola semplice...
    Le regole non sono mai complicate, è il ragionamento che sta dietro alle regole che lo può essere. E, secondo quello che diceva migliorabile, qui non è possibile approfondire troppo il ragionamento, perché dipende dal compilatore. Per questo chiedevo se, anche nel caso che allocassi una stringa in memoria dinamica facendo una new e non una new[], potessi fare delete e non delete[]. La domanda è lecita per il semplice motivo che faccio new ma alloco un array, e quindi c'è contraddizione, e di conseguenza viene spontaneo chiedersi come risolvere la contraddizione in fase di liberazione della memoria. Visto che il ragionamento diventa troppo complicato (sempre secondo quello che diceva migliorabile) mi chiedevo se ci fosse una regola da applicare che risolvesse questa situazione.
  • Re: Stringhe in memoria dinamica

    Occhio che new[] è la versione esplicativa di
    type *test = new type[DIM]
  • Re: Stringhe in memoria dinamica

    Autodidatta ha scritto:


    dipende dal compilatore
    Queste sono regole che dipendono dalle specifiche del linguaggio, non dai compilatori (che possono seguirle o meno, ma è un altro discorso).
    allocassi una stringa in memoria dinamica facendo una new e non una new[], potessi fare delete e non delete[]
    L'errore che fai è che consideri stringa questa

    char *s = new char;

    e invece è solo un puntatore ad un singolo carattere, che deallochi con una semplice delete.
    Se pensi di inserire una stringa con

    cin >> s;

    hai un crash (sempre per quelle regole semplici).

    Se, invece, scrivi

    char *s = new char[100];

    allora stai allocando una stringa (array di char) e solo allora utilizzerai delete[]

    Per questo dicevo che è semplice ...
    quindi c'è contraddizione
    Nessuna contraddizione ...
  • Re: Stringhe in memoria dinamica

    oregon ha scritto:


    Autodidatta ha scritto:


    dipende dal compilatore
    Queste sono regole che dipendono dalle specifiche del linguaggio, non dai compilatori (che possono seguirle o meno, ma è un altro discorso).
    allocassi una stringa in memoria dinamica facendo una new e non una new[], potessi fare delete e non delete[]
    L'errore che fai è che consideri stringa questa

    char *s = new char;

    e invece è solo un puntatore ad un singolo carattere, che deallochi con una semplice delete.
    Se pensi di inserire una stringa con

    cin >> s;

    hai un crash (sempre per quelle regole semplici).

    Se, invece, scrivi

    char *s = new char[100];

    allora stai allocando una stringa (array di char) e solo allora utilizzerai delete[]

    Per questo dicevo che è semplice ...
    quindi c'è contraddizione
    Nessuna contraddizione ...
    Chiaro. Però hai dimenticato un caso:

    char* s = new char;
    s = "Zorro";

    deduco che in questo caso non venga messa in memoria libera ma nell'area codice e quindi non devo fare né delete né delete[].
  • Re: Stringhe in memoria dinamica

    Autodidatta ha scritto:


    Chiaro. Però hai dimenticato un caso
    No, perché quello che evidenzi non è un caso ma un grave errore di trattamento dei puntatori ...
    
    char* s = new char;
    s = "Zorro";
    
    In questo modo hai allocato un carattere e assegnato il relativo puntatore. Poi questo puntatore lo "perdi" (di fatto rendendo non deallocabile quel carattere che causerà un memory leak) e lo sostituisci con un altro puntatore a testo costante.
    deduco che in questo caso non venga messa in memoria libera ma nell'area codice e quindi non devo fare né delete né delete[].
    La delete andava fatta perché, la regola semplice, impone una delete per ogni new. Solo che hai causato un memory leak e non puoi più usare il valore originale del puntatore per la delete.
  • Re: Stringhe in memoria dinamica

    oregon ha scritto:


    Autodidatta ha scritto:


    Chiaro. Però hai dimenticato un caso
    No, perché quello che evidenzi non è un caso ma un altro errore di trattamento dei puntatori ...
    
    char* s = new char;
    s = "Zorro";
    
    In questo modo hai allocato un carattere e assegnato il relativo puntatore. Poi questo puntatore lo "perdi" (di fatto rendendo non deallocabile quel carattere che causerà un memory leak) e lo sostituisci con un altro puntatore a testo costante.
    deduco che in questo caso non venga messa in memoria libera ma nell'area codice e quindi non devo fare né delete né delete[].
    La delete andava fatta perché, la regola semplice, impone una delete per ogni new. Solo che hai causato un memory leak e non puoi più usare il valore originale del puntatore per la delete.
    Sì è vero, meglio evitare questa cosa quando alloco con new. Però non ho capito una cosa: cambiando il valore del puntatore, perché devo comunque fare la delete? Se faccio una cosa del genere (anche se non va fatta), delete non causa un malfunzionamento (faccio delete su un puntatore che punta a qualcosa che non sta in memoria libera)?
  • Re: Stringhe in memoria dinamica

    Forse non ci capiamo ...

    Devi fare la delete per la new che hai fatto ... Il valore del puntatore che usi per la new e la delete deve essere il medesimo. Se cambi puntatore, ti ho detto, causi un problema di memory leak.

    Per una assegnazione di un puntatore come

    char *p = "ciao";

    non va fatta la delete perché non c'è la new ...
Devi accedere o registrarti per scrivere nel forum
44 risposte