CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 32
  1. #1
    Join Date
    May 2006
    Posts
    66

    List iterator not dereferencable

    I'm getting a debug assertion failure when trying to dereference a std::list iterator: "list iterator not dereferencable". Normally I'd try to reproduce the problem in a simple way, but I can't figure out how with this problem, so I'll just show screenshots of the important code and stuff from the debugger.

    The first is a screenshot just before stepping over the line where the dereference happens. And in the Watch tab, it shows the iterator pointing to exactly what I want/expect it to:

    http://i1091.photobucket.com/albums/...y25/before.jpg

    But immediately after stepping over that line I get:

    http://i1091.photobucket.com/albums/...by25/after.jpg

    So I really don't understand why I can't dereference an iterator to something which appears to be completely valid. Any help? Thanks!

    EDIT: ComListIt is defined here:

    Code:
    class Entity
    {
        public:
    
    ...
    
            typedef std::list<Component*> ComList;
            typedef ComList::iterator ComListIt;
    
    ...
    
    };
    Last edited by Koiby25; June 26th, 2011 at 02:55 PM.

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: List iterator not dereferencable

    Presumably, getComponent() is returning an invalid iterator. I'm not sure exactly what that's doing or how it relates to hasComponent(), so I can't be more specific.

  3. #3
    Join Date
    May 2006
    Posts
    66

    Re: List iterator not dereferencable

    What's an "invalid iterator" then? How could it be invalid if it points to what I want?

  4. #4
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: List iterator not dereferencable

    What does the assertion tell you if you press Retry to debug?
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  5. #5
    Join Date
    May 2006
    Posts
    66

    Re: List iterator not dereferencable

    I'm not entirely sure what you mean by that. Looking at the callstack shows this code:

    Code:
    	reference operator*() const
    		{	// return designated value
     #if _ITERATOR_DEBUG_LEVEL == 2
    		if (this->_Getcont() == 0
    			|| this->_Ptr == 0
    			|| this->_Ptr == ((_Mylist *)this->_Getcont())->_Myhead)
    			{	// report error
    			_DEBUG_ERROR("list iterator not dereferencable");
    			_SCL_SECURE_OUT_OF_RANGE;
    			}
    
     #elif _ITERATOR_DEBUG_LEVEL == 1
    		_SCL_SECURE_VALIDATE(this->_Getcont() != 0 && this->_Ptr != 0);
    		_SCL_SECURE_VALIDATE_RANGE(this->_Ptr !=
    			((_Mylist *)this->_Getcont())->_Myhead);
     #endif /* _ITERATOR_DEBUG_LEVEL */
    
    		return (_Mylist::_Myval(this->_Ptr));
    		}
    and _DEBUG_ERROR breaks.

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

    Re: List iterator not dereferencable

    Quote Originally Posted by Koiby25 View Post
    I'm not entirely sure what you mean by that. Looking at the callstack shows this code:
    The issue is that the code you wrote doesn't work, and the code you're showing us is just reporting that you've done something wrong.

    You're returning an invalid iterator. More than likely, you're dereferencing an invalid iterator using operator *.

    It doesn't take a lot of code to duplicate this error:
    Code:
    #include <list>
    
    int main()
    {
       std::list<int> IntList;
       IntList.push_back(10);
    
       std::list<int>::iterator it = IntList.end();
       int theInt = *it;  // boom, you're dead
    }
    Do you see what happened in the code above? I created a list added an int, and attempted to dereference the end() iterator. This leads to undefined behaviour, possibly a crash.

    The end() iterator can be used to mark the end of a range -- you can't dereference it however using operator*, and I suspect your code is doing something similar to that.

    Which leads to the question -- what happens if getComponent() doesn't find the id? Aha, a bug since getComponent() may be trying to tell you that it can't find what you're looking for, and instead is returning to you an invalid iterator which you're trying to dereference. In all likelihood, you should be comparing your iterator to end() before you try to dereference it.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 26th, 2011 at 05:31 PM.

  7. #7
    Join Date
    May 2006
    Posts
    66

    Re: List iterator not dereferencable

    Did you bother to read my posts or look at the images I posted, Paul McKenzie? I know you're trying to appear helpful, but don't patronize me.
    Last edited by Koiby25; June 26th, 2011 at 05:51 PM.

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: List iterator not dereferencable

    You haven't show us enough to really figure out what's going on.

    Iterators can be invalid for all sorts of reasons. Uninitialized iterators are of course always invalid; a past-the-end iterator (usually equal to container.end()) will be invalid; sometimes iterators can be invalidated by modifications to the underlying container, although I think in the case of std::list that only happens if the element referenced by the iterator is erased.

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

    Re: List iterator not dereferencable

    Quote Originally Posted by Koiby25 View Post
    Did you bother to read my posts or look at the images I posted, Paul McKenzie? I know you're trying to appear helpful, but don't patronize me.
    What have I stated that appears to be patronizing?

    The runtime detected an invalid iterator -- you are showing us the runtime code to determine that the iterator is invalid. As a matter of fact, look at the operator that is being used -- operator*. I showed you exactly how something like that can happen. Dereferencing the end() iterator results in the same crash you are witnessing now. Dereferencing end() is one of the biggest reasons for invalid iterator errors.

    All I did was ask a simple question -- if getComponent() fails to find the ID, what happens? How do you check if it found the ID? I looked at your code, and you are obviously assuming that getComponent() returns a valid iterator when it did not, and you're now dereferencing that iterator.

    It would also helo if you posted getComponent(). Then we can see exactly what it does and how it behaves if the ID is not found. As I stated, if that function returns end() to state that the ID cannot be found, then dereferencing the returned iterator without checking for end() is a flaw in your code that needs to be addressed. Don't shoot the messenger.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 26th, 2011 at 08:56 PM.

  10. #10
    Join Date
    May 2006
    Posts
    66

    Re: List iterator not dereferencable

    I feel like you're ignoring my "before" picture. The debugger watch thing shows that the iterator "it" references a valid "Component" pointer (ComGrid to be specific, which is derived from Component). This ComGrid element happens to be exactly what I want/expect the iterator to reference. You'll just have to trust me about that. And everything's right there according to the debugger, but I just can't dereference it.

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

    Re: List iterator not dereferencable

    Quote Originally Posted by Koiby25 View Post
    I feel like you're ignoring my "before" picture. The debugger watch thing shows that the iterator "it" references a valid "Component" pointer (ComGrid to be specific, which is derived from Component). This ComGrid element happens to be exactly what I want/expect the iterator to reference. You'll just have to trust me about that. And everything's right there according to the debugger, but I just can't dereference it.
    You cannot determine if an iterator or a pointer is pointing to valid memory by looking at the contents in the debugger. That is the mistake you're making.

    When an iterator is invalid, the contents of what it's pointing to may look good, but it means nothing. The same thing with an invalid pointer -- what is being pointed to may look OK, but that is just a consequence of what is in memory at that position. What could be happening is what Lindley is stating -- the iterator used to point to a valid entry, then it was invalidated, but your program still refers to this invalid iterator. Invalidating an iterator does not guarantee that what it was pointing to "goes away".

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; June 26th, 2011 at 09:03 PM.

  12. #12
    Join Date
    May 2006
    Posts
    66

    Re: List iterator not dereferencable

    Well why didn't you just say that in the first place? :P

    Anyway, I'll look into it and post more details if I can figure out what's relevant. That list iterator should never be invalidated as far as I can tell.

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

    Re: List iterator not dereferencable

    Quote Originally Posted by Koiby25 View Post
    Well why didn't you just say that in the first place? :P
    Because I'm explaining why and how an iterator can become invalid. Isn't that what you're asking -- what is an invalid iterator and how it can happen?
    'll look into it and post more details if I can figure out what's relevant. That list iterator should never be invalidated as far as I can tell.
    Again, your getComponent() function is the key to all of this, and we still don't know how it is implemented. If it indeed returns to you end() on failure, then your code that derefences the iterator is not correct -- it should be checking for end() before attempting to dereference.

    Regards,

    Paul McKenzie

  14. #14
    Join Date
    May 2006
    Posts
    66

    Re: List iterator not dereferencable

    (EDIT: Deleting. I don't think what I said made sense. Still can't figure out how the iterator got invalidated.)
    Last edited by Koiby25; June 27th, 2011 at 01:12 AM.

  15. #15
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: List iterator not dereferencable

    Seeing the code for getComponent() would undoubtedly help everyone to go beyond educated guesses.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Page 1 of 3 123 LastLast

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