"destroying" an object means its memory is reclaimed and its content might be altered (mainly if the hand-written destructor do so, and possibly as a result of storing free-memory-related stuff in place). list::erase returns you a new iterator that you should use instead of the one that was passed as argument (I'd be tempted to make i = l.erase(i);
an habbit).
In no way do destruction imply that memory is swept, wiped out. Previously valid location are still valid in most cases from the CPU's point of view (ie. it can fetch values), but can't be relied on because other operation may recycle that location for any purpose at any time.
You're unlikely to see *i
throwing a segfault, imho -- although that might happen with more complex types that use pointers, but you might see it having new values.
Other collections might have a more previsible behaviour than list. IIrc, a vector would compact the storage area so the previous value would only be seen by further dereferencing i
in rare cases.