Game Development Community

T3D 1.1 Beta 3 - Access violation in LangFile::freeTable during compile in VS 2005 Empty Project Template - RESOLVED

by Koh Hwee Miin · in Torque 3D Professional · 09/24/2010 (6:41 am) · 4 replies

Access violation in LangFile::freeTable() at the line "delete [] mStringTable[i]", when compiled T3D 1.1 Beta 3 with Visual Studio 2005 Pro.

Step to produce:
1. Create a new Torque 3D project with Empty Template from FPS Example.
2. Run Torque3D/My Projects/next/generateProjects.bat.
3. Open Visual Studio 2005 solution.
4. Add following Console function:
ConsoleFunction(TestLang, void, 1, 1, "")
{
    LangFile file("English");
    file.setString(1, "hello world");
}
5. Compile the solution.
6. Open Torque3D/My Projects/next/game/main.cs
7. Added a call to TestLang() right before onStart():
....
// Either display the help message or startup the app.
if ($displayHelp) {
   enableWinConsole(true);
   displayHelp();
   quit();
}
else {
   TestLang();
   onStart();
   echo("Engine initialized...");
}
....
8. Run the game and it will crash.

#1
09/24/2010 (3:11 pm)
Logged as TQA-1145 for the QA team to verify.
#2
10/15/2010 (2:41 am)
I found it caused by LangFile::setString().
If the string id starts from 0, it will be ok.
But if string starts from 1. The pointer in mStringTable[0] will be wild.
Then LangFile::freeTable() will crash the program.

After resizing, new allocated string pointer in the table must be set to NULL.



By the way, LangFile::setString() should call
SAFE_DELETE_ARRAY(mStringTable[id]);

before calling
mStringTable[id] = newstr;
#3
02/08/2011 (12:54 pm)
Greetings!

I don't believe the LangFile::setString() method was intended to be used that way. Normally you want to load in a language file that has all of the strings defined for the given language.

Having said that, I've gone ahead and made the changes for 1.1 Final. Certainly the addition of SAFE_DELETE_ARRAY(mStringTable[id]); is a good fix and prevents a memory leak.

Here's the method with my changes:

void LangFile::setString(U32 id, const UTF8 *str)
{
   if(id >= mStringTable.size())
   {
      U32 oldsize = mStringTable.size();
      mStringTable.setSize(id+1);
      for( U32 i=oldsize; i<mStringTable.size(); ++i )
      {
         mStringTable[i] = NULL;
      }
   }

   SAFE_DELETE_ARRAY(mStringTable[id]);

   UTF8 *newstr = new UTF8 [dStrlen(str) + 1];
   dStrcpy(newstr, str);
   mStringTable[id] = newstr;
}

- Dave
#4
04/22/2011 (4:59 pm)
Fixed in 1.1 Final and Preview.