Game Development Community

Thread related memory leak

by Faraz Ahmed · in Torque Game Engine · 05/24/2007 (1:40 am) · 5 replies

Hi, I was wondering whether someone could shed some light onto this memory leak problem. When implementing the below scenario, the executable starts leaking 4-8k a second (can be seen via the task manager) when the script counter reaches the mid 300's. In release mode the leak starts after about 500. The source of the problem is the call to dAtoi. Commenting out dAtoi fixes the leak. I apologize for not providing any overall context of where I'm using this code but I've deliberately kept it simple for clarity. The code below can be pasted directly into a test instance of TGE 1.5 for exact replication of the scenario.

The script code:
$cnt = 0;
function memoryLeak()
{
	echo("cnt=" SPC $cnt);
	$cnt++;
	
	if(isObject(leaker)) leaker.delete();
	new oLeaker(leaker);
	leaker.go();
		
	schedule(50, 0, "memoryLeak");
}

The C++ header file (oLeaker.h):
#ifndef _PLATFORMTHREAD_H_
#include "platform/platformThread.h"
#endif

class oLeaker : public SimObject
{
	typedef SimObject Parent;
   
public:
	oLeaker();
	~oLeaker();

	void go();

	Thread* mThread;
	static void launchThread(void* obj);
	
	void goThread();
	
	DECLARE_CONOBJECT(oLeaker);
	
};

The C++ source file (oLeaker.cc):
#include "console/consoleTypes.h" 
#include "console/simBase.h"
#include "oLeaker.h"

oLeaker::oLeaker()
{
	mThread = NULL;
}

oLeaker::~oLeaker()
{
	if(mThread != NULL) delete mThread;
	mThread = NULL;
}

IMPLEMENT_CONOBJECT(oLeaker);

void oLeaker::go()
{
	mThread = new Thread((ThreadRunFunction)launchThread, (S32) this, 1);	
}

void oLeaker::launchThread(void* obj)
{
	oLeaker* pThis = (oLeaker*)obj;
	pThis->goThread();	
}

void oLeaker::goThread()
{
	const char* x = "45";
	int i = dAtoi(x); // comment this out to stop memory leak
}

ConsoleMethod( oLeaker, go, void, 2, 2, "" )
{
	object->go();
}

#1
05/24/2007 (6:50 am)
What version of Torque (1.5, 1.5.1, 1.52?), and what compiler are you using?

This is really odd behavior which I'll test in a bit.
#2
05/24/2007 (6:53 am)
Off the top of my head, if you are using VS2005 (any version), there may be a problem with the usage of a deprecated method.

dAtoi simply calls atoi, which I believe was deprecated. Some very odd bugs and problems have occurred for me recently when using deprecated functions that perform string manipulation and conversion.

*EDIT*-Nope, atoi is one of the few methods not deprecated, so I guess this requires further investigation.
#3
05/24/2007 (9:50 am)
If I remember correctly atoi() is evidently not always thread safe and has been deprecated in favor of strtol().
#4
05/24/2007 (11:19 am)
I didn't get the annoying "*** has been deprecated. Use _*** instead" message for atoi when I tested it in another application.

I'm digging deeper, but again, the answer might rely on what compiler Faraz is using.
#5
05/24/2007 (9:19 pm)
I'm using Visual C++ 7.1 and TGE 1.5.0

Also, strtol() is exhibiting the same memory leak.

There seem to be other major leak issues associated with threads. For example, the below scenarios cause an immediate and constantly ticking memory leak:

Replace the function above with:
void oLeaker::goThread()
{
	char* myString = new char[128];
	myString[0] = '[[62810190b99a0]]';
	delete[] myString;
}


Or replace the function above with:
void oLeaker::goThread()
{
	Con::executef(1, "myCallback");
}

Wonder if there is a pattern here or some basic compiler setting that I may have gotten wrong.


P.S For the first problem, I'm at the moment using a work around by adding a custom atoi member function to the leaker class.