Thread: Dereferencing and Equality?

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    110

    Dereferencing and Equality?

    Sooo I'm working on a problem that requires me to use iterators. What im trying to do is test for equality of items in two lists that is being traversed with 2 separate iterators. However I am getting an error when I run my code, saying list iterator not dereferencable. I am pretty sure my two things are list iterators. Trying to debug it, it goes to these few lines first...

    Code:
    if(*current != *sorted_index){
    	while(*current != *sorted_index){
    		current++;
    	}
    }
    So I was wondering if what I wrote is actually proper to do. Thank you!

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As a basic principle, there is nothing wrong with that code. The if-statement is unnecessary, as the while-loop will not be entered if the current is matching sorted_index.

    If the object has a not-equal operator (operator!=), you may want to check that this operator does what it should do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Perhaps you run out over the end of a container (if the items are never equal)? In this case you also must check both iterators for end().
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    If none of the items are equal to *sorted_index then current will eventually reach end() and attempt to compare that to *sorted_index.
    You would need something like this:
    Code:
    while (current != myContainer.end() && *current != *sorted_index) {
    	++current;
    }
    However you're basically doing the job of std::find. Assuming you are either using a built-in type in the list, or you have a compatible less-than operator defined as well, just do this:
    Code:
    current = std::find(myContainer.begin(), myContainer.end(), *sorted_index);
    if (current != myContainer.end())
    {
    	// we found it! - do our thing with it now...
    }
    Part of the point of std::find is that since you don't have to write the loop yourself, you wont get it wrong (as you have here).
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    hmm.. I think it may be better if I posted my whole code...At this point I believe there are a lot of errors, and I haven't cleaned it up yet to make it shorter. However I can't do that if it doesn't work at all....

    Code:
    #include <iostream>
    #include <list>
    #include <string>
    
    using std::cout;
    using std::endl;
    using std::string;
    using std::cin;
    using std::list;
    
    int main(){
    	
    	//asks for user input
    	cout << "Please type in your input: ";
    	
    	//the container
    	list<string> sentence;
    	string x;
    	
    	//adds user input to container
    	while(cin >> x){
    		sentence.push_back(x);
    		}
    	
    	list<string> sorted = sentence;
    	sorted.sort();
    
        //starts container from beginning, and continues until the end
    	for(list<string>::iterator iter = sentence.begin(); iter != sentence.end(); iter++){
    		//set the current index to the iterator
    		list<string>::iterator current = sentence.begin();
    		//set the sorted index
    		list<string>::iterator sorted_index = sorted.begin();
            
    
    		//while the count is not equal to the end
    		while(sorted_index != sorted.end()){
    			//if the current is not equal to the end of the container
    			//output object 
    			if(*current != *sorted_index){
    					current++;
    				}
    			//else set the current to the beginning and output
    			else{
    				cout << *current << ' ';
    				for(list<string>::iterator count = sentence.begin(); count != sentence.end(); count++){
    					if(*current != *(sentence.end())){
    							current++;
    							cout << *current << ' ';
    						}
    					else{
    						//set current back to the beginning
    						current = sentence.begin();
    						//output the current
    						cout << *current << ' ';
    						//increment current
    						current++;
    					}
    		//for the sake of a new line
    		cout << endl;
    				}
    			}
    		//increment the sorted index
    		sorted_index++;
    		}
    	}
    
    	return 0;
    }
    The code here should take in a phrase, for example "The quick brown fox", and output

    Code:
    brown fox The quick       
    fox The quick brown       
    quick brown fox The      
    The quick brown fox
    I am trying to do a permuted index problem and this is only the beginning step. It would be great if I could get further assistance though.

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    This is the problem:
    Code:
    			if(*current != *(sentence.end())){
    You can never dereference an 'end' iterator, and again *current will also fail if the collection is empty.
    What you want in this case is just
    Code:
     if (current != sentence.end())
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    so I fixed that and added

    Code:
    if(current != sentence.end() && *current != *sorted_index){
    	current++;
    				}
    from

    Code:
    if(*current != *sorted_index){
    	current++;
    				}

    Here is my entire code...

    Code:
    #include <iostream>
    #include <list>
    #include <string>
    
    using std::cout;
    using std::endl;
    using std::string;
    using std::cin;
    using std::list;
    
    int main(){
    	
    	//asks for user input
    	cout << "Please type in your input: ";
    	
    	//the container
    	list<string> sentence;
    	string x;
    	
    	//adds user input to container
    	while(cin >> x){
    		sentence.push_back(x);
    		}
    	
    	list<string> sorted = sentence;
    	sorted.sort();
    
        //starts container from beginning, and continues until the end
    	for(list<string>::iterator iter = sentence.begin(); iter != sentence.end(); iter++){
    		
    		//set the current index to the iterator
    		list<string>::iterator current = sentence.begin();
    		//set the sorted index
    		list<string>::iterator sorted_index = sorted.begin();
            
    
    		//while the count is not equal to the end
    		while(sorted_index != sorted.end()){
    			
    			//if the current is not equal to the end of the container
    			//output object 
    			if(current != sentence.end() && *current != *sorted_index){
    					current++;
    				}
    			
    			else{
    				
    				//output the current since it must equal to the sorted_index object
    				cout << *current << ' ';
    				
    				//start the for loop on the "second" count because of the sorted_index output
    				for(list<string>::iterator count = sentence.begin()++; count != sentence.end(); count++){
    					
    					//if the current is not the end of the sentence 
    					//increment current and output the next word
    					if(current != sentence.end()){
    							current++;
    							cout << *current << ' ';
    						}
    
                        //since current is at the end
    					else{
    						//set current back to the beginning
    						current = sentence.begin();
    						//output the current
    						cout << *current << ' ';
    						//increment current
    						current++;
    						}
    				}
    				
    			//for the sake of a new line
    			cout << endl;
    			}
    
    		//increment the sorted index
    		sorted_index++;
    		}
    	}
    
    	return 0;
    }
    Now it simply does nothing...I type in a sentence and the program just simply ends, telling me to press enter to continue. I went through my code, and to me at the moment nothing stands out that could be wrong. Could someone just nudge me into the right direction please? Thanks!

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    It sounds like you have no debugger? Or is it that you just don't know how to use it?
    Either way, I think that to get any furthur in programming you're going to need to get used to using a debugger.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    Honestly I really do not know how to use the debugger. I use Visual Studio to do my programming. I've tried using it, but end up not understanding what its telling me. Right now Im not at home, so I can not pull up the debugging messages, but is there a guide out there on how to understand it? I've searched but a lot of it just tells me how to start the debugging but not understand it.

  10. #10
    Registered User
    Join Date
    Nov 2008
    Posts
    110
    soo...I found out if I have this

    Code:
    if(current != sentence.end() && *current != *sorted_index){
    	current++;
    				}
    My program would crash giving me the "list iterator not dereferencable" error.

    However if I changed it back to

    Code:
    if(current != sentence.end()){
    	current++;
    				}
    It simply does nothing! "Press Enter to continue..."

    I've tried using the VS debugging tool and all I get is...


    Code:
    'permuted.exe': Loaded 'C:\Documents and Settings\Dung\My Documents\Visual Studio 2008\Projects\permuted\Debug\permuted.exe', Symbols loaded.
    'permuted.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'
    'permuted.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'
    'permuted.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcp90d.dll', Symbols loaded.
    'permuted.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcr90d.dll', Symbols loaded.
    The program '[4080] permuted.exe: Native' has exited with code 0 (0x0).
    This looks more like something is wrong with my system files...

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by dnguyen1022 View Post
    soo...I found out if I have this

    Code:
    if(current != sentence.end() && *current != *sorted_index){
    	current++;
    				}
    My program would crash giving me the "list iterator not dereferencable" error.

    However if I changed it back to

    Code:
    if(current != sentence.end()){
    	current++;
    				}
    It simply does nothing! "Press Enter to continue..."

    I've tried using the VS debugging tool and all I get is...


    Code:
    'permuted.exe': Loaded 'C:\Documents and Settings\Dung\My Documents\Visual Studio 2008\Projects\permuted\Debug\permuted.exe', Symbols loaded.
    'permuted.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'
    'permuted.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'
    'permuted.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcp90d.dll', Symbols loaded.
    'permuted.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcr90d.dll', Symbols loaded.
    The program '[4080] permuted.exe: Native' has exited with code 0 (0x0).
    This looks more like something is wrong with my system files...
    So the only time you print something is when that if statement you quoted is false. The only time that if statement you quoted is false is when current == sentence.end(). Trying to print *current, when current is an end of a list, will launch various nuclear missiles. If you don't have any nuclear missiles installed, then your program will just stop.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by dnguyen1022 View Post
    I've tried using the VS debugging tool and all I get is...


    Code:
    'permuted.exe': Loaded 'C:\Documents and Settings\Dung\My Documents\Visual Studio 2008\Projects\permuted\Debug\permuted.exe', Symbols loaded.
    'permuted.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'
    'permuted.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'
    'permuted.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcp90d.dll', Symbols loaded.
    'permuted.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcr90d.dll', Symbols loaded.
    The program '[4080] permuted.exe: Native' has exited with code 0 (0x0).
    This looks more like something is wrong with my system files...
    You can ignore those lines.
    What you need to familiarize yourself with is basic debugging functionality first.
    Those are: stepping (step in, step out, step over), breakpoints and watching variables.
    If you know those, then you can accomplish a lot.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    (...) you're going to need to get used to using a debugger.
    Real Programmers can read core dumps :-)

    http://www.pbm.com/~lindahl/real.programmers.html

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    But dnguyen1022 isn't a real programmer now, eh?
    Besides, while real programmers can read core dumps, real programmers shouldn't be afraid to use debuggers, simply because it's faster!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    But admit, the site is funny...

Popular pages Recent additions subscribe to a feed