Jump to content

  • Log In with Google      Sign In   
  • Create Account

- - - - -

Memory leak when doing an assign operation with a handle


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 Hardguy   Members   -  Reputation: 244

Like
0Likes
Like

Posted 12 January 2012 - 03:36 AM

Quickly summarized, the problem is that when I assign a value from a c++ created object (handle) to a script created one, memory is not freed properly.

The code looks like this:
cBoundingVolume@ pCharBV = GetBoundingVolume();
cBoundingVolume bvCopy = pCharBV;

This does not release the memory of cBoundingVolume (I am not sure of the exact script place the memory allocation takes place but can try and find out if needed) and I get a memory leak.

However,this code works just fine:

cBoundingVolume@ pCharBV = GetBoundingVolume();
cBoundingVolume bvCopy;

GetBoundingVolume is a c++ function and has this declartion:
cBoundingVolume@+ GetBoundingVolume()

I am guessing that the problem might be that I am not declaring the copy operator correctly?
Currently it looks like this:
RegisterOperator("cBoundingVolume &opAssign(const cBoundingVolume &in)", asMETHODPR(cBoundingVolume, operator =, (const cBoundingVolume &), cBoundingVolume &)  );
Do I need to do something different for it to work? (as in increasing a user count in cBoundingVolume?)

I was not sure exactly what code is needed, so just say if you need to see more in order to locate the problem!


Sponsor:

#2 Andreas Jonsson   Moderators   -  Reputation: 3450

Like
0Likes
Like

Posted 12 January 2012 - 03:20 PM

I'll look into this. I made some changes in version 2.22.1 to avoid making unnecessary copies with value assignments. It is quite possible that this has broken something.

The opAssign method shouldn't increase the refCount as it only works directly with references and not handles.


The cBoundingVolume is obviously a asOBJ_REF type. Does it have any other flags? Have you registered a copy constructor for it? Does it have a default constructor?
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#3 Andreas Jonsson   Moderators   -  Reputation: 3450

Like
0Likes
Like

Posted 12 January 2012 - 04:29 PM

I wasn't able to reproduce this problem either. It is possible the problem has been fixed in the latest SVN already.

This is the test case I wrote:


engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
bout.buffer = "";
engine->SetMessageCallback(asMETHOD(CBufferedOutStream, Callback), &bout, asCALL_THISCALL);

asIScriptModule *mod = engine->GetModule("", asGM_ALWAYS_CREATE);
mod->AddScriptSection("script",
  "class T { \n"
  "  T() {} \n"
// "  T(int v) {} \n"
  "  T &opAssign(const T&in o) {return this;} \n"
  "} \n"
  "T @Get() { return T(); } \n"
  "void main() { \n"
  "  T @t1 = Get(); \n"
  "  T t2 = t1; \n"
  "} \n");

r = mod->Build();
if( r < 0 )
  TEST_FAILED;

if( bout.buffer != "" )
{
  printf("%s", bout.buffer.c_str());
  TEST_FAILED;
}

r = ExecuteString(engine, "main()", mod);
if( r != asEXECUTION_FINISHED )
  TEST_FAILED;

engine->Release();

The main() function in the script produces the following bytecode:


void main()

Temps: 2

Variables:
001: T@ t1
003: T t2
002: T {noname}


	0   0 *	PUSH	 3
- 7,3 -
	1   3 *	SUSPEND
	2   3 *	VarDecl  0
	2   3 *	CALL	 34		   (T@ Get())
	4   3 *	STOREOBJ v2
	5   3 *	PshVPtr  v2
	6   4 *	PSF	  v1
	7   5 *	REFCPY   0xc9cde8
	9   4 *	FREE	 v2, 13225448
   11   4 *	POP	  1
- 8,3 -
   12   3 *	SUSPEND
   13   3 *	VarDecl  1
   13   3 *	ChkNullV v1
   14   3 *	VAR	  v1
   15   4 *	CALL	 32		   (T@ T())
   17   4 *	STOREOBJ v3
   18   4 *	PshVPtr  v3
   19   5 *	GETOBJREF 1
   20   5 *	CALLINTF 36		   (T& T::opAssign(const T&in))
- 9,2 -
   22   3 *	SUSPEND
   23   3 *	FREE	 v3, 13225448
   25   3 *	FREE	 v1, 13225448
   27   3 * 0:
   27   3 *	RET	  0

Can you show me the bytecode that is produced by your script? It should be similar to the above. If you use the debug version of the scripting library it will write a file with the bytecode for each compiled function in the directory AS_DEBUG.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#4 Hardguy   Members   -  Reputation: 244

Like
0Likes
Like

Posted 13 January 2012 - 02:50 AM

I only use

asOBJ_REF as flag.



Here are the factories:


[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][size=3][left]
[/left][/size][/font][/color]RegisterFactory("", Factory_cBoundingVolume_Default);
RegisterFactory("const cVector3f &in avMin, const cVector3f &in avMax", Factory_cBoundingVolume_MinMax);
RegisterFactory("const cVector3f &in avSize", Factory_cBoundingVolume_Size);

Here is the script:
void main()
{
cBoundingVolume @pBV = GetBV();
cBoundingVolume copyBV = pBV;

Print("Done!\n");
}

Here is the bytecode output:

void main()

Temps: 2, 10

Variables: 
 001: cBoundingVolume@ pBV
 003: cBoundingVolume copyBV
 002: cBoundingVolume {noname}
 010: tString {noname}


    0   0 *    PUSH     10
- 3,2 -
    1  10 *    SUSPEND
    2  10 *    VarDecl  0
    2  10 *    CALLSYS  4125           (cBoundingVolume@ GetBV())
    4  10 *    STOREOBJ v2
    5  10 *    PshVPtr  v2
    6  11 *    PSF      v1
    7  12 *    REFCPY   0x3dc6598
    9  11 *    FREE     v2, 64775576
   11  11 *    POP      1
- 4,2 -
   12  10 *    SUSPEND
   13  10 *    VarDecl  1
   13  10 *    ChkNullV v1
   14  10 *    VAR      v1
   15  11 *    CALLSYS  218           (cBoundingVolume@ _beh_2_())
   17  11 *    STOREOBJ v3
   18  11 *    PshVPtr  v3
   19  12 *    GETOBJREF 1
   20  12 *    CALLSYS  227           (cBoundingVolume& cBoundingVolume::opAssign(const cBoundingVolume&in))
- 6,2 -
   22  10 *    SUSPEND
   23  10 *    STR      0         (l:6 s:"Done!
")
   24  12 *    PSF      v10
   25  13 *    CALLSYS  351           (tString _string_factory_(const int, const uint8&))
   27  10 *    ObjInfo  v10, 1
   27  10 *    PSF      v10
   28  11 *    CALLSYS  4123           (void Print(tString&in))
   30  10 *    PSF      v10
   31  11 *    CALLSYS  343           (void tString::_beh_1_())
- 7,2 -
   33  10 *    ObjInfo  v10, 0
   33  10 *    SUSPEND
   34  10 *    FREE     v3, 64775576
   36  10 *    FREE     v1, 64775576
   38  10 * 0:
   38  10 *    RET      0



#5 Hardguy   Members   -  Reputation: 244

Like
0Likes
Like

Posted 13 January 2012 - 02:53 AM

And that test produces a memory leak.


#6 Andreas Jonsson   Moderators   -  Reputation: 3450

Like
0Likes
Like

Posted 13 January 2012 - 03:12 PM

The bytecode produced looks ok. It is freeing the objects properly.

I think the problem might be in your implementation of the opAssign method.

Are you by any chance copying the ref counter too? That mustn't be done as it would screw up the memory management.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

#7 Hardguy   Members   -  Reputation: 244

Like
0Likes
Like

Posted 10 February 2012 - 10:33 AM

Late reply

Are you by any chance copying the ref counter too? That mustn't be done as it would screw up the memory management.


Ah yes! That was the problem! Thanks!


#8 Andreas Jonsson   Moderators   -  Reputation: 3450

Like
0Likes
Like

Posted 10 February 2012 - 08:26 PM

Ah, good to know. One less bug to worry about :)
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS