CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Sep 2010
    Posts
    17

    Question Can't figure out vector incompatible iterators problem

    I wrote this code:

    Code:
    	int arr[] =  {10,20,30,40,50};
    	static std::vector<int> nums(arr, arr+sizeof(arr)/sizeof(arr[0]));
    	std::vector<int>::iterator it = nums.begin();
    	std::vector<int>::iterator en = nums.end();
    
    	for ( ; it != en ; ++it) {
    		it = nums.erase(it);
    	}
    Second iteration I get "vector iterators incompatible", during != operator.
    Can anyone say what's wrong?

  2. #2
    Join Date
    Jun 2009
    Location
    oklahoma
    Posts
    199

    Re: Can't figure out vector incompatible iterators problem

    not positive here, but can end() change when you erase?
    I always see this loop as
    Code:
    for (it = nums.begin(); it!=nums.end(); it++)
    {
    }
    Also,
    Code:
    it = nums.erase(it);
    Then, in your for loop, you have it++
    Won't this skip one?
    Last edited by jnmacd; October 5th, 2010 at 09:02 PM.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Can't figure out vector incompatible iterators problem

    Quote Originally Posted by jnmacd View Post
    not positive here, but can end() change when you erase?
    Any vector iterator can be invalidated when you erase.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Can't figure out vector incompatible iterators problem

    Quote Originally Posted by gmeir11 View Post
    I wrote this code:

    Code:
    	int arr[] =  {10,20,30,40,50};
    	static std::vector<int> nums(arr, arr+sizeof(arr)/sizeof(arr[0]));
    	std::vector<int>::iterator it = nums.begin();
    	std::vector<int>::iterator en = nums.end();
    
    	for ( ; it != en ; ++it) {
    		it = nums.erase(it);
    	}
    Second iteration I get "vector iterators incompatible", during != operator.
    Can anyone say what's wrong?
    "en" no longer points to end(), as erasing items in a vector invalidates iterators.

    Secondly, why not just call clear() if you want to erase all the elements?

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Jun 2009
    Location
    oklahoma
    Posts
    199

    Re: Can't figure out vector incompatible iterators problem

    Does that mean
    Code:
    it = nums.begin();
    nums.erase(it);
    it++;
    is not valid?

  6. #6
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Can't figure out vector incompatible iterators problem

    Quote Originally Posted by jnmacd View Post
    Does that mean
    Code:
    it = nums.begin();
    nums.erase(it);
    it++;
    is not valid?
    When the element in the vector(unlike std::list or deque) is erased, all the references of the iterators starting from the position erased no longer point to the same memory block. The rationale behind this is to keep the efficiency of the vector's performance, particularly the reallocation of the contigious memory block.

    What this mean is that if a loop starts erasing from the index[0], then all iterators are invalidated because no valid iterators can possibly have existed before the first. Likewise, If a loop starts erasing from the end, then all iterators are still valid unless the user purposedly assign iterators to the invalid range to begin with, thus,
    Code:
        for ( ; it != en; --en)
        {
            nums.erase(en - 1);
        }
    will likely not cause runtime error.
    For this reason, it is recommended to move the element to the back and pop it which is typically done with std::remove() preceeded by vector::erase()
    Last edited by potatoCode; October 5th, 2010 at 10:05 PM. Reason: fixed some words

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured