Free children of parent too?



  • On 19/05/2016 at 01:37, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:    
    Platform:      
    Language(s) :

    ---------
    I have an objectdata plugin with of course GetVirtualObjects.
    Here I create a parent with child's using Alloc.
    Then I do a SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, cd)
    and return GetVirtualObjects with this new polygone object.

    After the SendModelingCoomand and before return, I Free the original parent object.
    I am still getting memory leaks.

    Should I also Free the children of the parent?

    -Pim



  • On 19/05/2016 at 03:00, xxxxxxxx wrote:

    Here some stripped code of what I am doing to clarify my above question.

      
    BaseObject* CreateVirtualObject(BaseDocument* doc)
    {
      
        BaseObject* parent = BaseObject::Alloc(Ocube);
    	
        BaseObject* child1 = BaseObject::Alloc(Osphere);
        doc->InsertObject (child1, parent, nullptr);
      
        BaseObject* child2 = BaseObject::Alloc(Osphere);
        doc->InsertObject (child2, parent, nullptr);
        
        return parent;  
    }
      
    BaseObject* Slice4DObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
    {
        ...
        
        BaseObject* nullParent = BaseObject::Alloc(Onull);		//main object
      
        virtualObject = CreateVirtualObject(doc);
            
        //Create clone and make it editable
        
        //in orignal code, multiple virtualObject are created and inserted under the nullParent
        // loop
            ModelingCommandData cd;
            cd.doc = doc;
            cd.op = virtualObject;
            SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, cd)
            
            //Delete original created Object, we don't need it anymore
            virtualObject->Remove();    //Needed?  
            Free(virtualObject);
            
            res = static_cast<BaseObject*>(cd.result->GetIndex(0));
            doc->InsertObject(res, nullParent, nullptr);
        // end loop
        return nullParent;
    }
      
    
    


  • On 19/05/2016 at 06:02, xxxxxxxx wrote:

    You shouldn't be inserting *anything* into the active document from within GetVirtualObjects().  In order to make objects children of another object, do this:

    res->InsertUnderLast(nullParent);
    

    Unless you have inserted virtualObject under something or into something, you should not need to call Remove().  Again, though, you shouldn't be inserting into an active document from GetVirtualObjects() or anything called from it.  You can use non-active documents for, say, CurrentStateToObject or Join.  The object returned by GetVirtualObjects() is handled by C4D and 'inserted' into the document by C4D.  Basically, 'return nullParent' is handing control and ownership of that object (and its children) to C4D.

    Finally, when objects are inserted into a document or under another object and the document or the other object is freed, anything inserted will be freed also.



  • On 19/05/2016 at 11:13, xxxxxxxx wrote:

    Thanks for the explanation.

    A question about your remark on "Again, though, you shouldn't be inserting into an active document from GetVirtualObjects() or anything called from it.  You can use non-active documents for, say, CurrentStateToObject or Join. "

    Does this mean, that I cannot get the document from GetVirtualObjects(BaseObject* op ... ?
    See below code.

    How to get document information for the SendModelingCommand?

    In this post https://plugincafe.maxon.net/topic/8615/11259_make-editable-example-solved
    I see that Andreas uses: cd.doc = hh->GetDocument();

    BaseObject* Slice4DObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
    {
      
    	BaseDocument* doc = op->GetDocument();
      
    	//Create clone and make it editable
    	ModelingCommandData cd;
    	cd.doc = doc;
    	cd.op = orgObject;
    	if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, cd)) {
    		GePrint ("Error Current State To Object Boolean."); 
    		return false;
    	}
    


  • On 19/05/2016 at 12:46, xxxxxxxx wrote:

    From the "Important Threading Information" in the API documentation:

    ObjectData::GetVirtualObjects() is of course allowed to do ANY modifications that do not modify the scene: as the object returned is not in the scene at that time it may be changed/created in any way necessary.

    If the object being modified using SendModelingCommand() is in the active document but the result is a new object not in the document, then you can use the active document.  In other cases, SendModelingCommand() directly modifies the object or replaces it.  In those cases, you can simply AutoAlloc<BaseDocument> pDoc;, insert the object being modified into that document (a clone if necessary!) and work on it.

    Also, the AtomArray returned is owned by the caller (you), so you might be seeing memory remaining from not releasing that:

    	BaseContainer	mbc;
    	mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE,		TRUE);
    	mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION,	FALSE);
    	mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_NOGENERATE,		FALSE);
    	ModelingCommandData	mcd;
    	mcd.doc =		doc;
    	mcd.flags =		MODELINGCOMMANDFLAGS_0;
    	mcd.bc =		&mbc;
    	mcd.mode =		MODELINGCOMMANDMODE_ALL;
    	mcd.op =		obj;
    	if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))
    	{
    		return (PolygonObject* )MessageSystem::NullThrow(GeLoadString(KDZS_ERR_GENERAL), "V4DObject.PolygonizeObject.SendModelingCommand(CURRENTSTATETOOBJECT)");
    	}
    	BaseObject*	cstoObj =	static_cast<BaseObject*>(mcd.result->GetIndex(0L));
    	AtomArray::Free(mcd.result);  // <==== THIS!!!
    	if (cstoObj == nullptr)
    		return (PolygonObject* )MessageSystem::NullThrow(GeLoadString(KDZS_ERR_GENERAL), "V4DObject.PolygonizeObject.cstoObj");
    	PolygonObject*	pop =	ToPoly(cstoObj);
    


  • On 19/05/2016 at 13:29, xxxxxxxx wrote:

    So, now I have following code:

    		AutoAlloc<BaseDocument> pDoc;
      
    		BaseContainer mbc;
    		mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE,		TRUE);
    		mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION,	FALSE);
    		mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_NOGENERATE,		FALSE);
    		ModelingCommandData mcd;
    		mcd.doc =		pDoc;
    		mcd.flags =		MODELINGCOMMANDFLAGS_0;
    		mcd.bc =		&mbc;
    		mcd.mode =		MODELINGCOMMANDMODE_ALL;
    		mcd.op =		orgObject;
    		if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))
    		{
    			//return (PolygonObject* )MessageSystem::NullThrow(GeLoadString(KDZS_ERR_GENERAL), "V4DObject.PolygonizeObject.SendModelingCommand(CURRENTSTATETOOBJECT)");
    			GePrint ("Error Current State To Object Boolean."); 
    			return false;
    		}
    		BaseObject*	cstoObj =	static_cast<BaseObject*>(mcd.result->GetIndex(0L));
    		AtomArray::Free(mcd.result);  // <==== THIS!!!
    		if (cstoObj == nullptr) {
    			//return (PolygonObject* )MessageSystem::NullThrow(GeLoadString(KDZS_ERR_GENERAL), "V4DObject.PolygonizeObject.cstoObj");
    			GePrint ("Error Current State To Object Boolean."); 
    			return false;
    		}
      
    cstoObj ->InsertUnder(sliceNull);
    return sliceNull;
    

    I used AutoAlloc<BaseDocument> pDoc; to define another document.
    Do I have to Free() this (I do not think so)?

    Even with this code, I see memory leaks (memory usage is growing and not released,even when I stop cinema 4d).

    I use g_alloc=debug in the debugger, but I do not see a console window or memory leak information.
    I am using R15.



  • On 19/05/2016 at 13:58, xxxxxxxx wrote:

    AutoAlloc<> works like a smart pointer.  The memory/object allocated is automatically freed once it goes out of scope (in this case, once you exist GetVirtualObjects()).

    Have you determined that the leak is solely within GetVirtualObjects()?

    Additionally, looking at your original code (post), this could be a problem:

    BaseObject* CreateVirtualObject(BaseDocument* doc)
    {
        BaseObject* parent = BaseObject::Alloc(Ocube);
    // YOU MIGHT NEED TO DO THIS!
    doc->InsertObject(parent, nullptr, nullptr);
    // ...	
        BaseObject* child1 = BaseObject::Alloc(Osphere);
        doc->InsertObject (child1, parent, nullptr);
      
        BaseObject* child2 = BaseObject::Alloc(Osphere);
        doc->InsertObject (child2, parent, nullptr);
        
        return parent;  
    }
    

    You haven't inserted 'parent' into the BaseDocument!  Not sure how C4D handles this insertion but you may be losing objects in the process.



  • On 19/05/2016 at 14:52, xxxxxxxx wrote:

    Ok, AutoAlloc<>  is clear. I will remove the Free().

    When I remove the SendModelingCommand it seems to be ok.
    Memory is not increasing while running the plugin.

    "You haven't inserted 'parent' into the BaseDocument". 
    I thought you are not allowed to insert objects in CreateVirtualObject?

    Perhaps I was a bit too hasty.
    Using your SendModelingCommand memory is increasing slowly, 
    but gets freed / returned if cinema exists.
    However, not when I close the scene. Might this be, because the plugin is still running?
    If so, do I need to use PluginEnd()?

    -Pim



  • On 19/05/2016 at 17:47, xxxxxxxx wrote:

    Again, you should use the temporary document for insertion to avoid inserting into the live document.

    I always include PluginEnd() but it doesn't do anything in my plugins.

    The extra memory from SMC() could be internal.  The only thing that you are getting back that has to be freed is that AtomArray.  Something that I have never really checked is to see if any remaining objects in the AtomArray are automatically freed with the array.  Typically, the returned result is simply one object (which were using).  Check the AtomArray count and see if maybe it has other elements (?).



  • On 19/05/2016 at 23:50, xxxxxxxx wrote:

    The AtomArray count is always 1.
    GePrint("AtomArray Count: " + String::IntToString(mcd.result->GetCount()));

    What about the BaseContainer mbc;
    Should that be Free()?

    I am now thinking of doing the currentstatetoobject different.
    Create the objects in getvirtual, but converting them to polygon objects in a different plugin (triggered by a message).

    -Pim



  • On 20/05/2016 at 07:47, xxxxxxxx wrote:

    I have added -g_alloc=debug to the debugger setting and now there is a console.
    When closing cinema it tells me:
    *** Potential Memory Leak Detected: See Visual Studio Debug Output for more details. ***

    The debug output is:
    *** Potential Memory Leak Detected: See Visual Studio Debug Output for more details ***

    First-chance exception at 0x00007FFEDA92A6D8 in CINEMA 4D 64 Bit.exe: 0xC0000005: Access violation executing location 0x00007FFEDA92A6D8.
    Unhandled exception at 0x00007FFEDA92A6D8 in CINEMA 4D 64 Bit.exe: 0xC0000005: Access violation executing location 0x00007FFEDA92A6D8.
    The program '[6824] CINEMA 4D 64 Bit.exe' has exited with code 0 (0x0).

    More output:
    Memory Leaks Detected:
    c:\program files\maxon\cinema 4d r15.057\resource\_api\c4d_string.cpp (10) : 3 Memory leaks of 13 bytes (, first leak at 000001FC7F60D8A0)
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\modeling\source\Dave\Modeling\ModelingBase.cpp (823) : 2 Memory leaks of 8 bytes (, first leak at 000001FC0D7FE1A0)
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\modeling\source\Dave\Modeling\ModelingBase.cpp (826) : 2 Memory leaks of 408 bytes (, first leak at 000001FC1A4D3280)
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\objects\source\primitive\PrimitiveObject.cpp (1050) : 2 Memory leaks of 16 bytes (, first leak at 000001FC0D7FD020)
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\objects\source\primitive\PrimitiveObject.cpp (1096) : 2 Memory leaks of 16 bytes (, first leak at 000001FC0D7FB5A0)
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\objects\source homas\Boole\boolobjectdata.h (218) : 2 Memory leaks of 416 bytes (, first leak at 000001FC1A4D2E80)
    p:\c4d_perforce_work\release\15.0\work\futurama\frameworks\core\source\datastructures\basearray.h (255) : 2 Memory leaks of 128 bytes (, first leak at 000001FC1A524F80)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\Atom.cpp (518) : 8 Memory leaks of 64 bytes (, first leak at 000001FC17C36340)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\BaseObject.cpp (1934) : 2 Memory leaks of 64 bytes (, first leak at 000001FC17C31140)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\BaseObject.cpp (2189) : 6 Memory leaks of 64 bytes (, first leak at 000001FC17C36240)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\BaseObject.cpp (2469) : 2 Memory leaks of 24 bytes (, first leak at 000001FC1A4C1AC0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\BaseTag.cpp (162) : 12 Memory leaks of 64 bytes (, first leak at 000001FC17C2C640)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\VariableTag.cpp (27) : 14 Memory leaks of 72 bytes (, first leak at 000001FC17C2C340)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\VariableTag.cpp (162) : 12 Memory leaks of 72 bytes (, first leak at 000001FC17C360C0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 4 Memory leaks of 48 bytes (, first leak at 000001FC1A4C2360)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 96 bytes (, first leak at 000001FC1A5254C0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 4 Memory leaks of 192 bytes (, first leak at 000001FC1A547A60)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 576 bytes (, first leak at 000001FC122F5660)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 2592 bytes () at 000001FC0332FDE0
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 2880 bytes (, first leak at 000001FC0332B760)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 3480 bytes () at 000001FC188A1D80
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 4336 bytes () at 000001FC0D841400
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 5184 bytes () at 000001FC0D845B40
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 6072 bytes () at 000001FC080E6340
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 6336 bytes (, first leak at 000001FC080E23C0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 8672 bytes () at 000001FC134DE840
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 10392 bytes (, first leak at 000001FC134D5900)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 12672 bytes (, first leak at 000001FC0D7A7580)
    p:\c4d_perforce_work\release\15.0\work\src\PHILIP\Common\BaseSelect.cpp (961) : Memory leak of 144 bytes () at 000001FC1A525400
    p:\c4d_perforce_work\release\15.0\work\src\PHILIP\Common\BaseSelect.cpp (961) : Memory leak of 160 bytes () at 000001FC1A547360
    p:\c4d_perforce_work\release\15.0\work\src\PHILIP\Objects\PolygonObject.cpp (11007) : 6 Memory leaks of 16 bytes (, first leak at 000001FC0D7FD520)
    p:\c4d_perforce_work\release\15.0\work\src\Philip\Objects\NullObject.cpp (18) : 2 Memory leaks of 16 bytes (, first leak at 000001FC0D7FD3A0)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (64) : 8 Memory leaks of 2072 bytes (, first leak at 000001FC03320720)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (74) : 6 Memory leaks of 3456 bytes (, first leak at 000001FC18897040)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (79) : 4 Memory leaks of 2384 bytes (, first leak at 000001FC03325960)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (92) : 10 Memory leaks of 800 bytes (, first leak at 000001FC1211EE80)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (95) : 6 Memory leaks of 800 bytes (, first leak at 000001FC1211DD00)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (96) : 6 Memory leaks of 776 bytes (, first leak at 000001FC1211F200)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (106) : 6 Memory leaks of 1096 bytes (, first leak at 000001FC1866A9E0)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (108) : 4 Memory leaks of 800 bytes (, first leak at 000001FC1211B680)
    p:\c4d_perforce_work\release\15.0\work\src\philip\pluginsystem\pluginlayer.cpp (404) : 12 Memory leaks of 32 bytes (, first leak at 000001FC1A4C33E0)
    p:\c4d_perforce_work\release\15.0\work\src\philip\pluginsystem\pluginlayer.cpp (781) : 2 Memory leaks of 32 bytes (, first leak at 000001FC1A4CE240)
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_container.cpp (526) : 2 Memory leaks of 24 bytes (, first leak at 000001FC1A534A20)
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_smart_link.cpp (337) : 4 Memory leaks of 72 bytes (, first leak at 000001FC17C38AC0)
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_smart_link.cpp (449) : 36 Memory leaks of 40 bytes (, first leak at 000001FC0A9E3B80)
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_smart_link.cpp (568) : 52 Memory leaks of 72 bytes (, first leak at 000001FC17C410C0)
    p:\c4d_perforce_work\release\15.0\work\src homas\btree_container.cpp (2422) : 14 Memory leaks of 32 bytes (, first leak at 000001FC1A535CE0)
    p:\c4d_perforce_work\release\15.0\work\src homas\btree_container.cpp (2465) : 84 Memory leaks of 32 bytes (, first leak at 000001FC1A538E00)
    p:\c4d_perforce_work\release\15.0\work\src ilo\hierarchyhelp.cpp (227) : 4 Memory leaks of 64 bytes (, first leak at 000001FC17C2C2C0)
    p:\c4d_perforce_work\release\15.0\work\src ilo\hierarchyhelp.cpp (231) : 4 Memory leaks of 40 bytes (, first leak at 000001FC0A9E6760)
    50 blocks not freed

    Any hints what this might mean?

    I will do the same in R17.



  • On 21/05/2016 at 04:10, xxxxxxxx wrote:

    Ok, the issue is definitely in "Current State To Object".
    I created a test objectdata plugin which creates a parent Null with A cube and a cone as child's.
    Normally the parent is a boolean, but for test purposes I change it to a null.

    I debug cinema 4d R15 using the debug console and I start the plugin.
    Then I quit cinema and the console tells me there is a memory leak.

    Here the plugin code, stripped to the bone.

    #include "c4d.h"
    #include "main.h"
      
    #define PLUGIN_ID_CONTROL   1037334  
    #define PLUGIN_ID_OBJECT    1037333 
      
    class Slice4DObject : public ObjectData
    {
      
    public:
    	static NodeData* Alloc(void) { return NewObjClear(Slice4DObject); }
    	virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
    };
      
    BaseObject* Slice4DObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
    {
    	Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_MATRIX | DIRTYFLAGS_DATA);
    	if (!dirty)
    		return op->GetCache(hh);	//controlObject->GetCache(hh);
      
    	BaseObject* parentObject = BaseObject::Alloc(Onull);
    	BaseObject* cone = BaseObject::Alloc(Ocone); 
    	cone->InsertUnder(parentObject);
    	BaseObject* cube = BaseObject::Alloc(Ocube); 
    	cube->InsertUnder(parentObject);
        
    	//Current state to object
    	AutoAlloc<BaseDocument> pDoc;
    	BaseContainer	mbc;
    	mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE,		TRUE);
    	mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION,	FALSE);
    	mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_NOGENERATE,		FALSE);
    	ModelingCommandData	mcd;
    	mcd.doc =		pDoc;
    	mcd.flags =		MODELINGCOMMANDFLAGS_0;
    	mcd.bc =		&mbc;
    	mcd.mode =		MODELINGCOMMANDMODE_ALL;
    	mcd.op =		parentObject;
    	if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))
    	{
    		//return (PolygonObject* )MessageSystem::NullThrow(GeLoadString(KDZS_ERR_GENERAL), "V4DObject.PolygonizeObject.SendModelingCommand(CURRENTSTATETOOBJECT)");
    		GePrint ("Error Current State To Object Boolean."); 
    		return false;
    	}
    	BaseObject*	cstoObj =	static_cast<BaseObject*>(mcd.result->GetIndex(0L));
    	GePrint("AtomArray Count: " + String::IntToString(mcd.result->GetCount()));
    	AtomArray::Free(mcd.result);  // <==== THIS!!!
    	if (cstoObj == nullptr) {
    		//return (PolygonObject* )MessageSystem::NullThrow(GeLoadString(KDZS_ERR_GENERAL), "V4DObject.PolygonizeObject.cstoObj");
    		GePrint ("Error Current State To Object Boolean."); 
    		return false;
    	}
      
        return cstoObj;	
      
    }
      
    Bool RegisterSlice4DV2Object(void)
    {
      
    	String PluginName = "Test";
      
    	Bool ret = RegisterObjectPlugin(PLUGIN_ID_OBJECT, PluginName, OBJECT_GENERATOR, Slice4DObject::Alloc, "", AutoBitmap("icon.png"), 0);
    	if (ret) GePrint(PluginName + " initialized.");
    	else GePrint ("Error initializing " + PluginName);
    	return ret;
    }
      
    

    And here the memory leak console output:

    Memory Leaks Detected:
    c:\program files\maxon\cinema 4d r15.057\resource\_api\c4d_string.cpp (10) : 2 Memory leaks of 13 bytes (, first leak at 0000025D478AD8C0)
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\objects\source\primitive\PrimitiveObject.cpp (1050) : Memory leak of 16 bytes () at 0000025D553B4020
    p:\c4d_perforce_work\release\15.0\work\bin\resource\modules\objects\source\primitive\PrimitiveObject.cpp (1096) : Memory leak of 16 bytes () at 0000025D553B3FE0
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\BaseObject.cpp (1934) : 2 Memory leaks of 64 bytes (, first leak at 0000025D59D9EBA0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\BaseObject.cpp (2189) : 2 Memory leaks of 64 bytes (, first leak at 0000025D59D9E3A0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\VariableTag.cpp (27) : 6 Memory leaks of 72 bytes (, first leak at 0000025D59D9E2A0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\VariableTag.cpp (162) : 4 Memory leaks of 72 bytes (, first leak at 0000025D59D9E0A0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 48 bytes (, first leak at 0000025D59D8D4C0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 96 bytes () at 0000025D59F500C0
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : 2 Memory leaks of 192 bytes (, first leak at 0000025D59DB54E0)
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 576 bytes () at 0000025D59F27280
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 2880 bytes () at 0000025D5699E880
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 6336 bytes () at 0000025D59D3F000
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 10392 bytes () at 0000025D5A19F7A0
    p:\c4d_perforce_work\release\15.0\work\src\Christian\COMMON\variabletag.h (35) : Memory leak of 12672 bytes () at 0000025D60EAF240
    p:\c4d_perforce_work\release\15.0\work\src\PHILIP\Objects\PolygonObject.cpp (11007) : 2 Memory leaks of 16 bytes (, first leak at 0000025D553B4060)
    p:\c4d_perforce_work\release\15.0\work\src\Philip\Objects\NullObject.cpp (18) : Memory leak of 16 bytes () at 0000025D553B3FA0
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (64) : 3 Memory leaks of 2072 bytes (, first leak at 0000025D56997EC0)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (74) : 2 Memory leaks of 3456 bytes (, first leak at 0000025D5A17FEE0)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (79) : 2 Memory leaks of 2384 bytes (, first leak at 0000025D5699D100)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (92) : 4 Memory leaks of 800 bytes (, first leak at 0000025D5B3D8A20)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (95) : 2 Memory leaks of 800 bytes (, first leak at 0000025D5B3D8DA0)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (106) : 2 Memory leaks of 1096 bytes (, first leak at 0000025D4A67CA00)
    p:\c4d_perforce_work\release\15.0\work\src\christian\register.cpp (108) : 2 Memory leaks of 800 bytes (, first leak at 0000025D5B3DA2A0)
    p:\c4d_perforce_work\release\15.0\work\src\philip\pluginsystem\pluginlayer.cpp (404) : 5 Memory leaks of 32 bytes (, first leak at 0000025D59D7CE40)
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_container.cpp (526) : Memory leak of 24 bytes () at 0000025D59D7D500
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_smart_link.cpp (449) : 12 Memory leaks of 40 bytes (, first leak at 0000025D59D8D340)
    p:\c4d_perforce_work\release\15.0\work\src\richard\genesis\ge_smart_link.cpp (568) : 14 Memory leaks of 72 bytes (, first leak at 0000025D59D9EC20)
    p:\c4d_perforce_work\release\15.0\work\src	homas\btree_container.cpp (2422) : 3 Memory leaks of 32 bytes (, first leak at 0000025D59D7CFC0)
    p:\c4d_perforce_work\release\15.0\work\src	homas\btree_container.cpp (2465) : 30 Memory leaks of 32 bytes (, first leak at 0000025D59D7EBE0)
    30 blocks not freed
      
    
    

    -Pim



  • On 21/05/2016 at 07:37, xxxxxxxx wrote:

    I was going to reply to the previous post but wanted to see if one of the Maxon Moderators had more insight.  Personally, all of these leaks appear to be internal to Cinema 4D.  I doubt this stuff would be allowed to remain in the release version.

    So, when you created your project, did you use the cinema4dsdk project as a template for your own?  I tend to do this even though I have plenty of existing projects based on it at some point.  But it depends on the C4D version.  For instance, for my newest plugin, I started with a fresh cinema4dsdk project since all of my others are for earlier versions.

    It may depend on the sub-version you are using as well.  I try to use the latest update since Maxon is continually fixing things.  15.064 is the last version they released for R15.



  • On 21/05/2016 at 09:10, xxxxxxxx wrote:

    Hi Robert, 
    Thanks for helping me.
    I am using r15, because cinema is not backwards compatibele.
    It is my experience that r15 compiled plugins run on  16 and 17. Not the other way around.

    Also I could not get the debug console working in r17.
    But i will try it again and compiled using r17.

    Pim



  • On 21/05/2016 at 14:49, xxxxxxxx wrote:

    This seems to work for me in R13.
    Instead of inserting the objects into the current document, and then sending them to a temp document. I inserted them into the temp document right away.
    That seems to have squashed the memory leak errors.

    BaseObject *MyGenerator::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)  
    {  
      Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_MATRIX | DIRTYFLAGS_DATA);  
      if (!dirty) return op->GetCache(hh);  
      //controlObject->GetCache(hh);  
      
      //Create a temp document where we will convert things later on to polygons  
      AutoAlloc<BaseDocument> pDoc;  
      
      BaseObject *parentObject = BaseObject::Alloc(Onull);    //Create a null object   
      pDoc->InsertObject(parentObject,nullptr, nullptr);      //Add it to the temp document  
      BaseObject *cone = BaseObject::Alloc(Ocone);            //Create a cone object      
      cone->InsertUnder(parentObject);                        //Add it as child of the null object  
      BaseObject *cube = BaseObject::Alloc(Ocube);            //Create a cube object  
      cube->SetAbsPos(Vector(0,100,0));                       //Move it awawy from the cone so we can see it  
      cube->InsertUnder(parentObject);                        //Add it as child of the null object  
      
      //Do a Current State To Object operation to convert the object to eitable polygons  
      BaseContainer mbc;  
      mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE, TRUE);  
      mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION, FALSE);  
      mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_NOGENERATE, FALSE);  
      ModelingCommandData    mcd;  
      mcd.doc = pDoc;  
      mcd.flags = MODELINGCOMMANDFLAGS_0;  
      mcd.bc = &mbc;  
      mcd.mode = MODELINGCOMMANDMODE_ALL;  
      mcd.op = parentObject;  
      if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))  
      {  
          GePrint("Error Current State To Object Boolean.");  
          return false;  
      }  
      
      BaseObject *cstoObj = static_cast<BaseObject*>(mcd.result->GetIndex(0L));      
      AtomArray::Free(mcd.result);  //<==== Free the memory!!  
      if(cstoObj == nullptr)  
      {  
          GePrint("Error Current State To Object Boolean.");  
          return false;  
      }  
      
      return cstoObj;      
    }
    

    -ScottA



  • On 22/05/2016 at 02:00, xxxxxxxx wrote:

    Yes, that solves the memory leak issues!

    I am only getting the "standard" R15 memory, but that one is always there. Even if my plugin is not there.

    Memory Leaks Detected:
    c:\program files\maxon\cinema 4d r15.057\resource\_api\c4d_string.cpp (10) : 2 Memory leaks of 13 bytes (, first leak at 000001DC7E57D9C0)
    1 blocks not freed
      
      
    *** Potential Memory Leak Detected: See Visual Studio Debug Output for more details ***
    

    I will not put the solution in my full code and see what appends.

    Thanks, Pim



  • On 22/05/2016 at 04:13, xxxxxxxx wrote:

    Yes, that solved the memory leaks.

    Robert and ScottA, thanks!

    -Pim



  • On 22/05/2016 at 04:46, xxxxxxxx wrote:

    Another quick question.

    It is ok now, no memory leaks.
    Except when I add following code, I get memory leaks again.
    What could be the reason for that. GetDown?

    // remove null created by csto
    if (cstoObj->GetType() == Onull){
        cstoObj = cstoObj->GetDown();  //get child under the Null
            if (! cstoObj)
                GePrint ("No child found under Bool.");
    }
    


  • On 22/05/2016 at 07:53, xxxxxxxx wrote:

    Right now cstoObj and it's children is your virtual object that is being generated.
    So I don't think you can do this: cstoObj = cstoObj->GetDown();
    If you want to grab one of the children of the null object. You'll need to split them apart into individual entities again. By using this:
    BaseObject *cone = cstoObj->GetDown();
    BaseObject *cube = cstoObj->GetDown()->GetNext();

    I don't use ObjectData plugins so I'm not the best at using them. But I think one of the main concepts is that you don't ever change the parent object. You only change the child objects.
    C4D needs to be in charge of freeing the virtual object's memory. So in general. If you get memory leaks. It probably means that you're trying to do something against the rules. Or your virtual object got clobbered by your code and C4D does not know how to free it's memory anymore.

    I'm not great at these kinds of plugins though.
    Perhaps the support guys can offer better information.

    -ScottA


Log in to reply