Thread: Going out of scope

  1. #1
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986

    Going out of scope

    Howdy guys.

    I have a loop that looks something like this:
    Code:
    while (1)
    {
      accept(SFD...);
      CONNECTION NewConn();
      NewConn.ReadRequest();
    }
    When this code is run, ReadRequest is called, and then there is an error:
    Debug Assertion Failed!
    Program: C:\blahblah...
    File: dbgheap.c
    Line: 1011

    Expression: _CrtIsValidHeapPointer(pUserData)

    For more information blah...
    dbgheap.c is not one of my files, so I expect its a microsoft one. I have tried not calling the ReadRequest function, and it works fine.

    The error is not in the function, but comes at the end of the block before the loop starts again. I expect the problem is that after the ReadRequest function is called and the NewConn goes out of scope, something happens on the heap.

    What should I be looking for in the ReadRequest function that could cause this sort of problem? I have no idea whats causing it nor do I fully understand the error, so any help would be greatly appreciated. Thanks

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>CONNECTION NewConn();
    I presume you actually meant:
    >>CONNECTION NewConn;
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    No, I meant what I posted. Thats not my real code, just a dumbed down version, it actually takes 2 arguments but I didn't bother to post them because you wouldn't care. Trust me when I say the problem is when it re-enters the loop the second time around. Can you just tell me what sort of things I should be looking for that can cause this sort of error? I can post all the code of the function and the CONNECTION class if you prefer. Thanks

  4. #4
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    I would look in the destructor for CONNECTION. It might be trying to access or delete a pointer that has already been deleted. Or if the error is actually during the call to ReadRequest (meaning ReadRequest is in the call stack), then go down the call stack until you get to code you recognize and look at the current location in the code to see what is being used. You might also have to check the line right before where the green arrow points. Chances are that something is being used right there that has already been deleted or destroyed.

    And of course if you want to post a dumbed down version of your code be careful not to post code that does something different than you intend. Your posted code declares a function named NewConn() that returns a CONNECTION, but what you meant was to declare a CONNECTION named NewConn with no constructor arguments. You'd have to completely remove the parentheses for that.

  5. #5
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Thanks JLou. My constructor for CONNECTION, apart from initializing a few variables, calls new on a variable, and my destructor just calls delete on it. Thats all the destructor does.

    If I dont call ReadRequest, theres no problems. But the error isn't in ReadRequest, it comes after it tries to enter the loop again. You see, I Beep() as the code enters the loop, and as it finishes the loop before entering again. After readRequest is called, I hear the beep at the end of the loop, but NOT when it enters again because thats when the error comes up.

    Heres my ReadRequest code, maybe you can see what I'm doing wrong?
    Code:
    bool CONNECTION::ReadRequest()
    {
      //----------------------------------------------------------------------------
      //      Set request variables
      //-----------------------------------------------------------------------------------------
      // First, read in the whole request
      char Buffer[10000];
      recv(SFD, Buffer, 10000, 0);
      
      string Word;                                  // Temporary place to store each word
      FullRequest = Buffer;
    
      //-----------------------------------------------------------------------------------------------------
      // Break off any POST data following a double newline
      int Position = FullRequest.find_last_of("\n\n") - 1;
      
      if (Position > 0)  
      {
        FullRequest[Position] = '\0';                        // Put a \0 where the \n\n are.
    
        for ( int C = Position + 2; FullRequest[C] != '\0'; C++)
        {
          //PostData << FullRequest[C];                        // Copy everything after that to the PostData
        }
      }
    
      
      //
      //-----------------------------------------------------------------------------------------------------
      // Split it into words
      istringstream IS(FullRequest);                          // Create an istringstream class
    
      //-----------------------------------------------------------------------------------------------------
      IS >> Word;                                    // The first word will be the request type
      
      //strupr(Word.c_str());                    
      if (!( strcmpi(Word.c_str(), "POST") ||                      // Check to see if its a method we support
         strcmpi(Word.c_str(), "GET")  ||
         strcmpi(Word.c_str(), "HEAD" )))
      {
        // Its not a request we like
        Status = 501;                                // Send a 501 Not Implemented
        return false;
      }
      
      
      //
      //-----------------------------------------------------------------------------------------------------
      RequestType = Word;                                // The request type was ok, assign it
      IS >> FileRequested;                              // The next word will be the requested file
      IS >> HTTPVersion;                                // Then the HTTP version
      IS >> Word;
      //-----------------------------------------------------------------------------------------------------
      // Map keys to values
      while (Word.length())
      {
        // Loop through, mapping keys to values
        if (HeaderMap[Word] != NULL)                        // Has there been a function assigned to this header?
        {
          HeaderMap[Word](IS, this);                        // If there has, call it!
        }
        // Now, check if its a MIME type. If it DOES NOT have ':' and DOES have '/', then its probably mime
        else if (!strstr(Word.c_str(), ":") && strstr(Word.c_str(), "/"))
        {
          if (strstr(Word.c_str() , ","))
          {
            // There is a comma at the end, get rid of it
            int Y = Word.length() - 1;
            Word[Y] = '\0';
          }
          Accepts[Word] = true;
        }
        IS >> Word;
      }
    
      
      //
      //-----------------------------------------------------------------------------------------------------
      // First, if the request is HTTP/1.1, there must be a host field
      if ( !strcmpi (HTTPVersion.c_str(), "HTTP/1.1") )
      {
        if (HostRequested.length() <= 0)
        {
          Status = 400;                              // No host was specified. Send 400 Bad Request
          return false;
        }
      }
      
      
      //
      //-----------------------------------------------------------------------------------------------------
      // Cut off absolute URL, making us able to serve all future HTTP versions.
      if (strstr( FileRequested.c_str() , "http://" ))                // If its an absolute URL
      {   
        IsAbsolute = true;                              // Start at the end of the http://
        int CurrLetter = FileRequested.find_first_of("http://") + 7;
        
        for (CurrLetter; FileRequested[CurrLetter] != '/'; CurrLetter++ )
        {
          HostRequested += FileRequested[CurrLetter];                // Copy to the new host.
        }
      } 
      
      
      //
      //-----------------------------------------------------------------------------------------------------
      // Figue out the virtual host
      ThisHost = &SWEBSGlobals.Host[HostRequested];            
      if(ThisHost->Root.length() < 1)                          // If there is an entry for the host in the VHI 
        UseVH = false;                                //  then it is a virtual host
      else UseVH = true;
    
      
      //
      //-----------------------------------------------------------------------------------------------------
      // Cut off query string
      int X = FileRequested.find_last_of('?') + 1;                  // Get the last '?' in the string
      if (X > 0)
      {
        int Y = X;                                  // Save position of X
        for (X; FileRequested[X] != '\0'; X++)                    // Copy everything after that to the extension
        {
          QueryString+= FileRequested[X];            
        }
        FileRequested[Y - 1] = '\0';                        // Chop it off at the '?'
      }
      
      
      //
      //-----------------------------------------------------------------------------------------------------
      // URL Encoding
      // %20 = " "
      int S = 0;
      while ((S = FileRequested.find("%20", 0)) != string::npos)
      {
        FileRequested.replace(S , 3, " ");
      }
    
      
      //
      //-----------------------------------------------------------------------------------------------------
      // Change slashes from *nix to windows
      for (int Z = 0; FileRequested[Z] != '\0'; Z++)                  // Replace / with \ 
      {
        if (FileRequested[Z] == '/') FileRequested[Z] = '\\';
      }
      
      
      //
      //-----------------------------------------------------------------------------------------------------
      // Assign full path based on virtual hosts
      if (UseVH) RealFile = ThisHost->Root + FileRequested;
      else RealFile = SWEBSGlobals.WebRoot + FileRequested;
        
      
      //
      // Check for a "..", if found send a 404. Because this will allow them to go one folder back, and 
      //  then get files from there, effectively giving full access to the system - thanks to Adam for pointing this out!
      if (strstr(RealFile.c_str() , ".."))
      {
        Status = 404;
        return false;
      }
    
      //-----------------------------------------------------------------------------------------------------
      // Check if the file is a folder
      DWORD hFile = GetFileAttributes(RealFile.c_str());
      if (hFile == FILE_INVALID)
      {
        
        Status = 404;                                // File does not exist. Return error 404
        return false;
      }
      
      
      //
      //-----------------------------------------------------------------------------------------------------
      if (hFile & FILE_ATTRIBUTE_DIRECTORY)        
      {
        IsFolder = true;                              // Is a folder
      }
      else  
      {                
        IsFolder = false;                              // Is not folder
      }
    
      
      //
      //-----------------------------------------------------------------------------------------------------  
      SetFileType();                                  // Set whether the file is binary or a script
      Status = 200;                                  // It passed all the tests, therefore its ok
      
      //
      return true;
    }

  6. #6
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    What about the call stack? Are you running this in the debugger?

    I didn't see anything on quick glance. It should be really easy to narrow it down with the debugger, especially since according to your signature you are using VC++. You should be able to see what exactly is being accessed at the point of the failure. Whatever that is, it was either deleted earlier or its memory was corrupted by accessing an array out of bounds or something like that.

    So in short, you should really use the debugger.

  7. #7
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Hmm this is strange. I have been compiling in debug in Visual C++ 6 like you thought, and somethings strange is happening. The error I get is in the file "dbgheap.c", but I did a search and I have no dbgheap.c on my computer.

    When I press Retry to debug the program, I am told a User breakpoint was called (or something like that). The ASM line looks like this:
    Code:
    100514B8   int         3
    I don't know ASM so I can't do much about it. And the code seems to be in dbgheap.c, but I can't look at that because it doesn't exist on my computer (a dialog comes up asking me to find it but I don't have it so I cancel).

    I also tried the same code that does the loop, replacing it with a goto statement. I figured since theres no parenthesis it might not go out of scope, but it still does.

  8. #8
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    I tried compiling everything in release mode, and it still didn't work. Now I get the error "The memory could not be 'written'..."

    I don't get this I'll go through cutting out bits of code to see if I can sort it out, but still I can't figure out why this is happening.

    BTW, lately my computers had a few problems. Every hour or so my screen goes completly crazy, as in parts of the windows appear where they shouldn't. I can't do anything and I am forced to Alt-F4 everything (my mouse is screwed and I cant see the cursor), then Ctrl-Alt-Delete and end task on explorer, and then start explorer again. Its windows 2000 and I've defraged and run Nod32 virus scanner on it, and it hasn't given me any problems. My virtual memory settings give me twice my ram size so I don't think thats a problem, and I have 1/4 of my hard drive empty. Must be time for a format soon

    EDIT:
    Out of curiosity, this is what the debugger shows
    Code:
    Loaded 'C:\SWEBS\SWEBSDLLTester\Release\SWEBSDLLTester.exe', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\NTDLL.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\KERNEL32.DLL', no matching symbolic information found.
    Loaded 'C:\SWEBS\SWEBSEngine\SWEBS\Release\SWEBS.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\ADVAPI32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\rpcrt4.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\wsock32.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\ws2_32.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\msvcrt.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\ws2help.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\OLE32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\GDI32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\USER32.DLL', no matching symbolic information found.
    Loaded 'C:\PHP\php-4.3.1-Win32\SAPI\php4isapi.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM\php4ts.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\OLEAUT32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\ODBC32.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\COMDLG32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\shlwapi.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\comctl32.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\SHELL32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\odbcint.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\imon.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\NTMARTA.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\WINSPOOL.DRV', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\mpr.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\WLDAP32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\samlib.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\ntdsapi.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\dnsapi.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\NETAPI32.DLL', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\secur32.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\netrap.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\msafd.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\rsvpsp.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\rapilib.dll', no matching symbolic information found.
    Loaded 'C:\WINDOWS\SYSTEM32\wshtcpip.dll', no matching symbolic information found.
    The thread 0x550 has exited with code 0 (0x0).

  9. #9
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Try this - Build your app in Debug mode (Build->Set Active Configuration and pick "Win32 Debug"). Then hit F5 to "Go". This is the same as clicking the menu command: Build->Start Debug->Go. Then run your test like you have been so that it gets the error.

    When the error occurs, close the disassembly window if it is open (side note: I like to go to Tools->Options, and in the Workspace tab check the box next to Disassembly so that it docks instead of becoming a window). Then open the Call Stack window by going to View->Debug Windows->Call Stack.

    With the call stack window open, resize it so you can see the function calls in it without too much trouble. Scroll down until you see the name of a function call that looks familiar to you (e.g. the destructor for CONNECTION). Double click on the function that looks familiar. It MSDev should open the file that contains that function call and it will have a green arrow pointing at the line that is currently executing (or sometimes the next line down).

    By looking at the call stack in this way you should be able to get more useful information than "100514B8 int 3". You might have to look at several different functions in the call stack to get the most information. If you can do this let us know what you find.

  10. #10
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>recv(SFD, Buffer, 10000, 0);
    You didn't catch the return value from this function call. recv() normally denotes the number of bytes received, 0 on socket closure, -1 on error (or something similar).

    If your app doesn't know how much data was put into the buffer, how do you expect to be able to process it?

    >>FullRequest = Buffer;
    What type of variable is Fullrequest? If it's anything string related (like a std::string), the program will probably crash if Buffer isn't complete. At the point in the program you issue this assignment, do you know for sure that Buffer is \0 terminated?
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. Nested loop frustration
    By caroundw5h in forum C Programming
    Replies: 14
    Last Post: 03-15-2004, 09:45 PM
  5. Question about C# scope rules
    By converge in forum C# Programming
    Replies: 3
    Last Post: 01-30-2002, 06:56 AM