why is this function leaking memory ?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/07/2008 at 18:45, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   10 
    Platform:      
    Language(s) :     C++  ;

    ---------
    Hi,

    i discovered that i have loads of mem leaks in my plugin, when i check the debug console.

    Im not sure why bc i always use autoalloc, and when i 'remove' an object i always free it myself afterwards.

    i tracked down the leaks to this function, so it must be something inside this piece of code:

    > \> /\*\* \> convert obj and all of its children in to one poly object and return it \> \*\*/ \> BaseObject\* MyTool::getPolyObject(BaseObject\* obj,BaseDocument\* doc){      \>       \>      // make a copy of the object \>      BaseObject \*copy = (BaseObject\* )obj->GetClone(COPY_NO_ANIMATION,NULL); \>      copy->SetPos(Vector(0,0,0)); copy->SetRot(Vector(0,0,0)); \>       \>      // convert to polys      \>     ModelingCommandData md1; md1.op = copy; md1.doc = doc; \>     if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, md1)) return NULL;      \>       \>      // select all objects in group \>      md1.op = static_cast<BaseObject\*>(md1.result->GetIndex(0)); \>      if(!SendModelingCommand(MCOMMAND_SELECTALL, md1)) return NULL;      \>       \>      // connect all \>      md1.op = static_cast<BaseObject\*>(md1.result->GetIndex(0)); \>     if(!SendModelingCommand(MCOMMAND_JOIN, md1)) return NULL;      \> \>      // do an optimize ( cant hurt probably ..) \>      md1.op = static_cast<BaseObject\*>(md1.result->GetIndex(0)); \>     if(!SendModelingCommand(MCOMMAND_OPTIMIZE, md1)) return NULL; \> \>      BaseObject\* result = static_cast<BaseObject\*>(md1.result->GetIndex(0)); \>       \>      return result;           \> } \>

    the code works, but it creates lots of mem leaks..

    can anybody see what's wrong with this ?
    i tried to free the copy object, but that makes cinema crash.. :(

    thanks in advance for your help ;-)



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/07/2008 at 20:19, xxxxxxxx wrote:

    You make a copy (clone) of the object 'obj' and never free it. Then you call SendModelingCommand() several times only returning the last result. The other objects still exist in memory and aren't freed unless you explicitly free them (BaseObject::Free(...)) or insert them into the document (doc->InsertObject(...)). Unfortunately, those results just don't disappear - you must do something with them.

    This will include MCOMMAND_CURRENTSTATETOOBJECT and probably MCOMMAND_JOIN.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/07/2008 at 02:17, xxxxxxxx wrote:

    Hi, thanks for your answer.

    But i dont quite understand, bc i thought there was only one result in the end, as all the following modelingCommands overwrite the result of the previous one ?

    In the end there's only the md1.result - object which i create a pointer to via static cast and return as result.

    later i free the result, so i thought id free all the modeling command objects as well, bc its a pointer on the same object ?
    am i wrong there ?

    also when i try to BaseObject::Free(copy) before i return result, cinema crashes, which i dont really understand..



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/07/2008 at 03:16, xxxxxxxx wrote:

    ok i freed the getClone object and the result of the modeling command:

    > \> . \> . \> BaseObject\* result = static_cast<BaseObject\*>(md1.result->GetIndex(0));      \>       \> // free stuff not needed anymore \> AtomArray::Free(md1.result); \> BaseObject::Free(objCopy); \> \> return result;                     \> } \>

    objCopy is the 'copy' object from my first post, i renamed it.

    i get no more crashes through the freeing, but the leaks are still there.

    not sure what else i should free now..



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/07/2008 at 04:29, xxxxxxxx wrote:

    in another post it says that ModellingCommand Destructor automatically deletes all its data, which would mean i dont have to delete anything inside the modeling command.

    see:
    http://www.plugincafe.com/forum/display_topic_threads.asp?ForumID=4&TopicID;=1914

    as i already delete the object generated by getClone(), i assume that the leaks can only be caused by the result that i return ?

    But that one is later free'd with BaseObject:Free
    so im a little clueless now..



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/07/2008 at 06:18, xxxxxxxx wrote:

    ok while trying to narrow down the cause of the leak, i split my original function in two:
    doCSTO and doJoin. (they are practically identical, besides the actual command used)

    then i call it like this:

    > \> BaseObject\* myTool::getPolyObject(BaseObject\* obj,BaseDocument\* doc){      \>       \>      BaseObject\* result = doCSTO(obj,doc); \>      result = doJoin(result,doc); \> \>      return result; \> } \>

    The funny thing now is, if i call only doCTSO, *OR* call only doJoin, there are no Leaks!

    if i call both, the leaks return..

    here again the code of the two (similar to first post) :

    > \> BaseObject\* doCSTO(BaseObject\* obj1,BaseDocument\* doc) \> {           \>      // make a copy of the object \>      BaseObject \*objCopy1 = (BaseObject\* )obj1->GetClone(COPY_NO_ANIMATION,NULL); \>      objCopy1->SetPos(Vector(0,0,0)); objCopy1->SetRot(Vector(0,0,0));      \>       \>      // convert to polys      \>     ModelingCommandData md1; md1.op = objCopy1; md1.doc = doc;      \>     if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, md1)) return NULL;                          \>       \>      BaseObject\* result = static_cast<BaseObject\*>(md1.result->GetIndex(0));      \>       \>      // free stuff not needed anymore \>      AtomArray::Free(md1.result); \>      BaseObject::Free(objCopy1); \>       \>      if(result) return result;                     \>      blDelete(result); \>      return NULL; \> } \> \> BaseObject\* doJoin(BaseObject\* obj2,BaseDocument\* doc) \> {                \>      // make a copy of the object \>      BaseObject \*objCopy2 = (BaseObject\* )obj2->GetClone(COPY_NO_ANIMATION,NULL); \>      objCopy2->SetPos(Vector(0,0,0)); objCopy2->SetRot(Vector(0,0,0));      \>                \>      // connect all      \>      ModelingCommandData md1; md1.op = objCopy2; md1.doc = doc;                               \>     if(!SendModelingCommand(MCOMMAND_JOIN, md1)) return NULL;      \>       \>      BaseObject\* result = static_cast<BaseObject\*>(md1.result->GetIndex(0));      \>       \>      // free stuff not needed anymore \>      AtomArray::Free(md1.result); \>      BaseObject::Free(objCopy2);      \>       \>      if(result) return result;                     \>      blDelete(result); \>      return NULL; \> } \>



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/07/2008 at 08:02, xxxxxxxx wrote:

    i found that when i manually delete all stuff in the ModelingCommand md1, the memory leaks get cut down by a good amount, like 90%..

    the rest is probably from some other part of code, so ill go and check the rest of my code now as well :-)



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/07/2008 at 08:56, xxxxxxxx wrote:

    Right. In the docs under ModelingCommandData 'result' it says:

    Note: You need to free created objects yourself afterwards, or insert them into a document.

    Each command that may result in a new object (like CurrentStateToObject or Join), creates a new one not just working on the one added to ::op. When inserted into a document, the document takes control of freeing the object but otherwise, you 'own' the created object in mdl.result and must free it. Same thing if you do obj->Remove() from a document: you must either reinsert back into some document or freeing becomes your responsibility.


Log in to reply