Visualizzazione dei risultati da 1 a 4 su 4

Hybrid View

  1. #1
    Quando cancelli un elemento da una std::list l'iteratore che hai usato non è più valido (se pensi a come è implementata una lista linkata la cosa dovrebbe essere ovvia). In ogni caso, proprio per gestire casi di questo tipo, std::list::erase restituisce un iteratore all'elemento successivo a quello che hai appena cancellato, per cui puoi fare:
    codice:
    while(iter!=b.end())        // /* Imposto l'iteratore iter , esso passa in rassegna
    {                           //  * ogni elemento della lista . Se l'elemento è dispari
        if((*iter)%2!=0)        //  * viene eliminato. */
            iter = b.erase(iter);
        else
            ++iter;
    }
    Amaro C++, il gusto pieno dell'undefined behavior.

  2. #2
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Quando cancelli un elemento da una std::list l'iteratore che hai usato non è più valido (se pensi a come è implementata una lista linkata la cosa dovrebbe essere ovvia). In ogni caso, proprio per gestire casi di questo tipo, std::list::erase restituisce un iteratore all'elemento successivo a quello che hai appena cancellato, per cui puoi fare:
    codice:
    while(iter!=b.end())        // /* Imposto l'iteratore iter , esso passa in rassegna
    {                           //  * ogni elemento della lista . Se l'elemento è dispari
        if((*iter)%2!=0)        //  * viene eliminato. */
            iter = b.erase(iter);
        else
            ++iter;
    }
    Il mio libro purtroppo non spiega bene questo concetto..

  3. #3
    Quote Originariamente inviata da themagiciant95 Visualizza il messaggio
    Il mio libro purtroppo non spiega bene questo concetto..
    Una lista linkata è una struttura in cui ciascun elemento è qualcosa di simile a questo:
    codice:
    struct Elem
    {
        Elem *next;
        Elem *prev;
        T payload;
    }
    dove "next" punta all'elemento successivo, "prev" al precedente e payload contiene il dato che effettivamente hai memorizzato. Un iteratore relativo ad una std::list sostanzialmente è un puntatore a questa struttura. Quando tu chiami la erase, concettualmente quello che succede è:
    codice:
    Elem *erase(Elem *pos)
    {
        // Aggiusta i puntatori dell'elemento precedente e successivo
        pos->prev->next = pos->next;
        pos->next->prev = pos->prev;
        Elem *ret = pos->next;
        delete pos;
        return ret;    
    }
    (ci sono un po' più di check e qualche corner case da gestire, a seconda della convenzione scelta per la gestione della "fine lista", ma il concetto è questo)
    Come vedi, l'iteratore che hai passato (pos) non è più valido al termine della funzione, dato che punta ad un elemento che è stato deallocato. Accedervi nuovamente risulterà in crash, corruzione di dati o "apparente funzionamento" in maniera più o meno casuale.
    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 © 2026 vBulletin Solutions, Inc. All rights reserved.