"Invalid allocation size" error. Help needed.

Posted on 2007-07-22
Last Modified: 2008-01-09
I am working on a C++ game application. It's being developed in Visual Studio C++ 2005, on a Windows XP SP2 machine, we use OGRE as our graphics engine, and Crazy Eddie GUI (CEGUI) for our user interfaces. When I attempt to run the game, it generates a breakpoint and this is the output:

First-chance exception at 0x7c812a5b in starClient_d.exe: Microsoft C++ exception: CEGUI::UnknownObjectException at memory location 0x0012d5b4..
HEAP[starClient_d.exe]: Invalid allocation size - CCCCCD11 (exceeded 7ffdefff)
starClient_d.exe has triggered a breakpoint

The breakpoint occurs in the following line of code:

return Ogre::MemoryManager::instance().op_new_vc( reportedSize, gProcessID );

The call stack looks like this:

>starClient_d.exe!operator new[](unsigned int reportedSize=3435973837)  Line 363 + 0x23 bytes (Code A)
 starClient_d.exe!Star::InDataStream::readString()  Line 121 + 0x4f bytes (Code B)
starClient_d.exe!Star::Journal::deserializeJournalData(Star::InDataStream & ids={...})  Line 346 + 0x34 bytes (Code C)
starClient_d.exe!Star::Report::Report(Star::InDataStream & inDataStream={...})  Line 40 (Code D)


Code A
inline void *operator new[](size_t reportedSize)
    if( !gProcessID )
        gProcessID = Ogre::MemoryManager::instance()._getProcessID();
 ERROR HERE==>   return Ogre::MemoryManager::instance().op_new_vc( reportedSize, gProcessID );

Code B

std::string InDataStream::readString()
      int length;

      // read the length first
      length = readInt();

LINE 121==>      char* buffer = new char[length + 1];
      //char buffer[50];

      // Now read the string.
      mIS->read(buffer, length * sizeof(char));

      buffer[length] = 0;

      std::string tmp_string(buffer);

      delete[] buffer;

      return std::string(tmp_string);

Code C
void Journal::deserializeJournalData(InDataStream& ids)
      //read the number of entries in this stream
      int numEntries = ids.readInt();

      //read the owner ID of this journal and set class data
      this->ownerID = ids.readInt();

      for(int i = 0; i < numEntries; i++)
            //read the current entryItem-type
            int itemType = ids.readInt();
            Entry* entry;

            //Use the enumerated type to check if the entryItem is a
            //text or picture item
            case TEXT_ITEM:
                  //create a new entry and add it to the ToC
                  entry = newEntry(new TextItem(" "));

                  //Insert the stored values in the stream into the newly created entry
                  //in the order they were written
LINE 346 ==>                  dynamic_cast<TextItem*>(entry->getEntryItemPtr())->setBody(ids.readString());

Code D

Report::Report(InDataStream& inDataStream)
            // Variables declaration and initialization.
            std::vector<Entry*> workTableOfContents = (*(this->getTableOfContents()));

            // Clear the vector of pointers to Entry objects.

LINE 40==>      }

Any help would be appreciated.

Question by:Lou1
    LVL 86

    Accepted Solution

    Seems that your input file is either invalid or processed incorrectly - since the length is read from the file using

          length = readInt();

    and then directly used for the allocation in

          char* buffer = new char[length + 1];

    the invalid allocation size of more than 2GB (0x7ffdefff - the *theoretical* limit) has its orifins here. I'd add some error handling code like

    #define _2GB 0x7ffdefff

          length = readInt();

          if (length > _2GB) {

              // error handling here

          char* buffer = new char[length + 1];

    LVL 6

    Assisted Solution

    Problem occurs in the length = readInt(); line of code B. The readInt function has returned an unexpected value (might be CCCCCD10, which exceeds the max-allowed value 7ffdefff).
    LVL 86

    Expert Comment

    Sorry, that's not 2GB, make that

    #define ALLOC_LIMIT 0x7ffdefff

          length = readInt();

          if (length > ALLOC_LIMIT) {

              // error handling here

          char* buffer = new char[length + 1];

    Author Comment

    FYI, the readInt function is as follows:

    int InDataStream::readInt()
          int value;
          mIS->read((char*)&value, sizeof(int));

          return value;

    Where mIS is declared as follows:

          // istream associated with this DataStream.
          std::istream *mIS;

    LVL 86

    Expert Comment

    That was cleat. Yet the input seems to be in a different format or corrupted. Check it or output the value after reading it vor debugging/verification purposes. BTW, is the file opened as 'binary'?
    LVL 39

    Expert Comment

    You should add some more error checking, i. e. the readInt has no error check nor an initialization and would return some random values on failing:

    int InDataStream::readInt()
          int value = 0;    // always init variables (it costs less than nano-seconds)
          if (mIS->read((char*)&value, sizeof(int)))
               return value;
         // throw exception or return 0 or -1 which was needed to be
         // checked by  the calling function as well

    >>>> dynamic_cast<TextItem*>(entry->getEntryItemPtr())->setBody(ids.readString());
    You should avoid statements like that. It is really bad code:

    1. there are really rare cases where dynamic casts were needed. Here it is not. A few lines above you create the TextItem by new. If you would save the pointer in a variable you wouldn't need the cast.

        TextItem* textentry = new TextItem(" ");
        entry = newEntry(textentry );
        std::string s = ids.readString();

    I wonder whether the TextItem was derived from a common baseclass. If not the dynamic_cast makes even less sense. If so, you should consider to make the setBody a virtual function of the baseclass wha tis much much better than using dynamic_cast.

    Regards, Alex


    Author Comment

    Well, I found out the error was occurring in another developer's code. I told them about their error and now it's up to them to fix it.

    But thanks to all who responded.

    Featured Post

    Highfive Gives IT Their Time Back

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
    Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
    The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
    The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

    734 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now