Question

Check this code:

#include "stdafx.h"
#include <list>

int _tmain(int argc, _TCHAR* argv[])
{
    std::list<int> mylist;
    mylist.push_back(1);
    std::list<int>::iterator i = mylist.end();
    if( i == mylist.end() )
        printf( "end is end\n" );

    mylist.clear();
    if( i == mylist.end() )
        printf( "never get here because Microsoft seems to "
                "think the iterator is no longer safe.\n" );

    return 0;
}

Now, according to cplusplus.com this shouldn't be a problem, and in release mode, I think this is fine and doesn't cause any issues really, but debugging becomes impossible as this just bails without letting me continue. Any pointers?

Était-ce utile?

La solution

Other answers point out that, in general, you can't rely on a container's past-the-end iterator remaining valid when the container is cleared. However, the past-the-end iterator of a list should indeed remain valid:

C++11 23.3.5.4/3 Effects: Invalidates only the iterators and references to the erased elements.

The past-the-end iterator does not refer to any element, so should not be invalidated.

Autres conseils

From C++11, Table 100 (Sequence container requirements):

clear() [...] may invalidate the past-the-end iterator.

And std::list is of course a sequence container template (23.3.5.1/2):

A list satisfies all of the requirements of a container, of a reversible container (given in two tables in 23.2), of a sequence container, including most of the optional sequence container requirements (23.2.3), and of an allocator-aware container (Table 99). The exceptions are the operator[] and at member functions, which are not provided. Descriptions are provided here only for operations on list that are not described in one of these tables or for operations where there is additional semantic information.

This is in fact invalid. Iterators are only valid on the current state container. Once you add or remove items, the iterator is no longer valid.

The article you link does not say what you are doing is valid. They get a new iterator after the clear.

The reason it doesn't show up in release code is because the debugging that picks up the issue is disabled.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top