Thread: string iterator not dereferencable

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    3

    string iterator not dereferencable

    I keep getting the error: "string iterator not dereferencable" and that leads me to the xstring class.

    Im using globals to fill up a variable called mDebugText.

    Globals.h
    Code:
    static OgreBasis* ogreBasis;
    Globals.cpp
    Code:
    OgreBasis* Globals::ogreBasis = 0;
    and in other files
    Code:
    char buf[256];
    char message[1024];
    rc=recvfrom(s,buf,256,0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
    sprintf(message, "Received data: %s\n",buf);
    Globals::ogreBasis->mFrameListener->mDebugText = tmes;
    As far as I can see there is nothing wrong with the contents of buf. Ive also been logging the contents of buf to see if the last value causes the crash. But there is nothing different about it.

    Because the debugger leads me to the xstring class im guessing the coversion from char[] to string causes the problem but why?

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    What is xstring? Is this a runtime or a compile-time error? (OK, this one is implied.) On what exact line to you get it?

    Anyway, you don't have any guarantee that buf is 0-terminated. Even it is under regular circumstances, that's still a gaping security hole.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    3
    Yes its a runtime error and im still very new to c++ but I found this about xstring:

    XString or the "Extended String Class" is a generic C++ class that can handle both ASCII and UNICODE strings.

    This is the piece of code where the debugger points me:

    Code:
    #if _HAS_ITERATOR_DEBUGGING
    		if (this->_Mycont == 0 || _Myptr == 0
    			|| _Myptr < ((_Mystring *)this->_Mycont)->_Myptr()
    			|| ((_Mystring *)this->_Mycont)->_Myptr()
    				+ ((_Mystring *)this->_Mycont)->_Mysize <= _Myptr)
    			{
    			_DEBUG_ERROR("string iterator not dereferencable");
    			_SCL_SECURE_OUT_OF_RANGE;
    			}
    		__analysis_assume(_Myptr != 0);
    It points to: _DEBUG_ERROR("string iterator not dereferencable");

    And yes it is 0-terminated. Here's the contents of the file UDPReader.cpp.

    Code:
    #include "UDPReader.h"
    #include "OgreBasis.h"
    
    UDPReader::UDPReader(char* host, int port) {
    
    	this->host = host;
    	this->port = port;
    	this->udpDispatcher = Globals::om->getObservable("udpDispatcher");
    
    }
    
    void UDPReader::run() {
    
    	long rc;
    	SOCKET s;
    	char buf[256];
    	SOCKADDR_IN addr;
    	SOCKADDR_IN remoteAddr;
    	int remoteAddrLen=sizeof(SOCKADDR_IN);
    	char message[1024];
    
    	s=socket(AF_INET,SOCK_DGRAM,0);
    
    	if(s == INVALID_SOCKET) {
    		//sprintf(message, "Error: Socket couldnot be created, error code: %d\n",WSAGetLastError());
    		//Globals::ogreBasis->mFrameListener->mDebugText = "Error: Socket couldnot be created, error code: ";
    
    	} else {
    		//sprintf(message, "UDP Socket created!\n");
    		//Globals::ogreBasis->mFrameListener->mDebugText = "UDP Socket created!";
    
    	}
    
    	addr.sin_family=AF_INET;
    	addr.sin_port=htons(this->port);
    
    	u_long host_addr = inet_addr(this->host.c_str());   
        u_long net_mask = inet_addr("255.255.255.0");   
        u_long net_addr = host_addr & net_mask;         // 172.16.64.0
        u_long dir_bcast_addr = net_addr | (~net_mask); // 172.16.95.255
    
    	addr.sin_addr.s_addr=htonl(INADDR_ANY);
    
    	rc=bind(s,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
    
    	if(rc == SOCKET_ERROR) {
    
    		//sprintf(message, "Error: bind, error code: %d\n",WSAGetLastError());
    		//Globals::ogreBasis->mFrameListener->mDebugText = "Error: bind, error code: ";
      
    	} else {
    
    		//sprintf(message, "Socket bound to port %d\n", this->port);
    		//Globals::ogreBasis->mFrameListener->mDebugText = "Socket bound to port ";
      
    	}
    
    	while(repeat) {
    
    		rc=recvfrom(s,buf,256,0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);
        
    		if(rc == SOCKET_ERROR) {
    
    			//sprintf(message, "Error: recvfrom, error code: %d\n",WSAGetLastError());
    			//Globals::ogreBasis->mFrameListener->mDebugText = "Error: recvfrom, error code: ";
        
    		} else {
    
    			//sprintf(message, "%d Bytes received!\n", rc);
    			//Globals::ogreBasis->mFrameListener->mDebugText = "Bytes received!";
    
    			buf[rc]='\0';
    		}
    
    		//sprintf(message, "Received data: %s\n",buf);
    		this->udpDispatcher->sendMessage(buf);
    		
    
    		sprintf(message, "Received data: %s\n",buf);
    		Globals::ogreBasis->mFrameListener->mDebugText = message;
    		//LogManager::getSingletonPtr()->logMessage(tmes);
    
    		
    	}
    
    	_endthread();
    
    }
    Last edited by bhalos; 10-10-2008 at 03:25 PM.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Are Globals::ogreBasis and Globals::ogreBasis->mFrameListener valid pointers?

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And yes it is 0-terminated.
    No, it's not. I can send your program 256 bytes of garbage and it will happily read those, and the memory beyond your 256-byte buffer too. At best, you'll get garbage output in the debug message. At worst, your program overwrites the stack with random (or is it?) data, leading to a crash or even a remote code execution.

    OK, so you're dealing with an invalid iterator. Where? The debugger has a stack trace. Go up the stack frames until you get to code that you wrote. The likelyhood of there being such a bug in libstdc++ is low.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    3
    Quote Originally Posted by Daved View Post
    Are Globals:greBasis and Globals:greBasis->mFrameListener valid pointers?
    Yes they are. Everything works fine at first but the prog always crashes at some point.

    Quote Originally Posted by CornedBee
    No, it's not. I can send your program 256 bytes ...
    Okay my bad. I thought this line:
    Code:
    buf[rc]='\0';
    took care of that.

    Ive narrowed the problem down to this line:
    Code:
    Globals::ogreBasis->mFrameListener->mDebugText = message;
    The call stack leads me to this:
    Code:
    		UTFString( const std::string& str ) {
    			_init();
    			assign( str );
    		}
    		//! destructor
    		~UTFString() {
    			_cleanBuffer();
    		}
    Code:
    	for ( i = str.begin(); i != ie; i++ ) {
    				utf8len = _utf8_char_length( static_cast<unsigned char>( *i ) ); // estimate bytes to load
    				for ( size_t j = 0; j < utf8len; j++ ) { // load the needed UTF-8 bytes
    					utf8buf[j] = ( static_cast<unsigned char>( *( i + j ) ) ); // we don't increment 'i' here just in case the estimate is wrong (shouldn't happen, but we're being careful)
    				}
    				utf8buf[utf8len] = 0; // nul terminate so we throw an exception before running off the end of the buffer
    				utf8len = _utf8_to_utf32( utf8buf, uc ); // do the UTF-8 -> UTF-32 conversion
    				i += utf8len - 1; // we subtract 1 for the increment of the 'for' loop
    
    				utf16len = _utf32_to_utf16( uc, utf16buff ); // UTF-32 -> UTF-16 conversion
    				append( utf16buff, utf16len ); // append the characters to the string
    			}
    			return *this;
    And then to xstring.

    All im doing is sending strings like this one: -0.304391xr0.506332yr-0.806829zr
    Which works at first but it always randomly crashes. Im guessing the contents of buf arent always valid? But when I check the log I dont see anything out of the ordinary.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, the debugger should allow you to inspect buf and message in this function. You should be able to tell you whether they are valid.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  2. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  3. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM