AutoAlloc<BaseLink> in std list [SOLVED]



  • On 24/04/2016 at 04:25, xxxxxxxx wrote:

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

    ---------
    Hello.

    I have the following code:

    class MyClass{
    public:
    	MyClass() {
    		structure.clear();
    	}
    	void addLink(AutoAlloc<BaseLink> c){
    		structure.push_back(c);
    	}
    private:
    	std::list<AutoAlloc<BaseLink>> structure;
      
    };
    

    It seems that I can't have a AutoAlloc<BaseLink> in std data structures (lists etc)

    As an alternative, I use the following class and the container uses pointers of this class (std::list<MyLinkClass*>) :

    class MyLinkClass {
    private:
    	AutoAlloc<BaseLink> link;
    	unsigned int other_irrelevant_data;
      
    public:
    	MyLinkClass(){}
    };
    

    Is there any better solution ?
    I need to store BaseLink objects in a container.

    Thank you.



  • On 25/04/2016 at 02:05, xxxxxxxx wrote:

    Hello,

    as usual one should avoid using elements of the standard library. Use build-in constructs like BaseArray instead. There is even a special class to manage an array of BaseLink objects: the class BaseLinkArray.

    Best wishes,
    Sebastian



  • On 06/05/2016 at 08:55, xxxxxxxx wrote:

    Hello peterakos,

    was your question answered?

    Best wishes,
    Sebastian



  • On 09/05/2016 at 02:24, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Hello,as usual one should avoid using elements of the standard library. Use build-in constructs like BaseArray instead.

    I only noticed some time ago that the SDK docs state that the STL should only be used if absolutely neccessary. What are the reasons for this? Exception handling? Something else?

    I have been using STL classes in my plugin for quite some time (before noticing the passage in the docs about avoiding them) without any apparent problems.



  • On 09/05/2016 at 05:22, xxxxxxxx wrote:

    I guess it's just safe-guarding against any issues that may arise from non-sdk data structures and therefore "blaming" MAXON for it.

    I am for example using STL in all my code (am not using build-in data structures at all) and never had any problem (though I know that if there is something not working I cannot fall back to the official support here but am on my own).



  • On 09/05/2016 at 06:41, xxxxxxxx wrote:

    Thanks Samir, good to know!



  • On 12/05/2016 at 00:39, xxxxxxxx wrote:

    Hello.

    I am trying to convert the STL data structures into maxon ones .

    I get the following issue:

    void anyFunction(BaseLinkArray param){
     //do something
    }
      
    //in other part of code
    BaseLinkArray base_link_array;
    anyFunction(base_link_array);
    

    The above code returns:
    error C2248: 'maxon::BaseArray<BaseLink *,0x010,BASEARRAYFLAGS_0,maxon::DefaultAllocator>::BaseArray' : cannot access private member declared in class 'maxon::BaseArray<BaseLink *,0x010,BASEARRAYFLAGS_0,maxon::DefaultAllocator>'

    The reason why i was avoiding maxon data structures is because i couldn't use them freely as I do with STL ones. 
    How can I solve the above error ?

    Thank you very much for your time.



  • On 12/05/2016 at 01:16, xxxxxxxx wrote:

    Hello again.

    I solve it like that:

    void anyFunction(BaseLinkArray& param){
    	BaseLinkArray copied;
    	copied.CopyFrom(param);
    }
    

    Is this the right way ?

    thnx.



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

    Hello,

    for such a complex data structure it is always best practice to hand it over to a function by reference or as a pointer.

    Best wishes,
    Sebastian



  • On 12/05/2016 at 02:29, xxxxxxxx wrote:

    I want to copy this data structure into a class' member.
    The problem is that the destructor of BaseLinkArray frees the objects that each base link points to.
    Can I avoid that ?

    The memory of these objects is handled by other container. What I want is a data structure with simple pointers to objects.



  • On 12/05/2016 at 04:37, xxxxxxxx wrote:

    BaseLinkArray (and most other c4d data structures) don't have copy constructors, that's why you cannot pass them by value (but by reference).

    Your copying procedure is fine.

    For storing pointers you can either use PointerArray or BaseArray<T*> (if you want to take ownership) I guess. But I am not using them myself so probably the support can give you a better answer on that.



  • On 12/05/2016 at 07:02, xxxxxxxx wrote:

    Hello.

    First of all, it is advised in the forum that to store a pointer to any Cinema4D object, a BaseLink has to be used. So I need a data structure with BaseLinks to BaseObjects.

    I also need to copy the contents of this data structure without losing the references to the original base objects. I have tried using BaseLinkArray, but it's desctructor frees the objects (I don't want that).

    I have also tried using BaseArray<BaseLink*> :

    AutoAlloc<BaseLink> temp_link;
    temp_link->SetLink(any_base_object);
    my_base_array->Append(temp_link);
    

    but it is wrong because the temp_link gets destroyed at the end of the block, so right after, the my_base_array is invalid.

    What can I do to solve this problem ?

    Thank you very much for your time.



  • On 12/05/2016 at 08:48, xxxxxxxx wrote:

    Hello,

    what exactly do you mean with "it's desctructor frees the objects"? Do you mean that the referenced scene objects are deleted? Can you provide some code that illustrates the issue?

    Best wishes,
    Sebastian



  • On 12/05/2016 at 10:01, xxxxxxxx wrote:

    Be aware that AutoAlloc<BaseLink> is not a pointer(!!), it's probably just a wrapper around a pointer (just like other smart pointers out there) to handle memory allocation/freeing automatically.

    And I am a bit confused about the wording you use. I think you mean pointer to the original c4d atoms right? Afai can see BaseLinkArray (same as the other data structures) does deallocate its content on destruction (which makes sense considering how the classes are designed), but this definetly shouldn't touch the c4d atoms the baselinks handle, so I guess you mean it frees the baselinks (which is correct)?

    As mentioned if you want to handle baselink pointers and take over ownership, BaseArray<BaseLink*> should be the way to go (if I look at the docs).

    I agree w Sebastian, some actual code will help clear things up (and save all of us time).



  • On 12/05/2016 at 15:14, xxxxxxxx wrote:

    Hello.

    @Katachi I cant use BaseLinkArray, because when I copy the array into another and then delete the original, the BaseLink pointers inside the second array are invalid.

    Here is why I cant BaseArray<BaseLink*> either :

    void testBaseLink(BaseDocument* doc) {
    	maxon::BaseArray<BaseLink*> base_array;
    	{
    		BaseObject* object = doc->GetFirstObject();
    		AutoAlloc<BaseLink> temp_link;
    		temp_link->SetLink(object);
    		base_array.Append(temp_link);
    		BaseList2D* valid = base_array[0]->GetLink(doc);
    	}
    	BaseList2D* invalid = base_array[0]->GetLink(doc);
    }
    

    The above code is just for testing to replicate the issue. At the end of the inner block, the first BaseLink inside the BaseArray becomes null.

    I want a data structure that calling CopyFrom, will clone the base links. Not simply copying the pointers.
    I would create my own data structure that stores base links, but BaseLink has private constructor and destructor.

    Thank you.



  • On 13/05/2016 at 01:43, xxxxxxxx wrote:

    Hello,

    in your example you again allocate a BaseLink with AutoAlloc but then you hand it over to a BaseArray using Append(). So the BaseArray is supposed to take ownership but since you use AutoAlloc the BaseLink object is deleted when the scope is left. Please make sure you understand what AutoAlloc is and what it does.

    Best wishes,
    Sebastian



  • On 13/05/2016 at 02:17, xxxxxxxx wrote:

    Hello.

    I understand that it is a smart pointer that keeps the code safe from memory leaks.
    I thought assigning the pointer to another object would increase some kind of counter and wouldn't delete it. Totally my mistake here.

    Thank you.


Log in to reply