Open Search
    Entity Creation and Destruction Manual (Cinema API)

    About

    Primitive data types and structures can be created on the stack. Complex data types, classes and dynamic memory have to be allocated using Cinema 4D's memory management system. Using Cinema 4D's memory management system increases the stability and speed of a plugin.

    Warning
    The creation of objects and references in the context of the Maxon API is described here: Entity Creation.

    Object Allocation

    New instances of generic classes should be allocated and freed with these functions:

    • NewObj(): Creates an object with the given constructor parameters.
    • DeleteObj(): Deletes the given object.
    Note
    Always check for nullptr when allocating memory.
    // This example allocates a new instance of the given object class.
    // A constructor parameter is handed over.
    // After the object is used it will be deleted.
    CustomClass* newObject = NewObj(CustomClass, 123) iferr_return;
    if (newObject != nullptr)
    {
    const Int32 number = newObject->GetNumber();
    ApplicationOutput("Number: @", number);
    DeleteObj(newObject);
    }
    #define ApplicationOutput(formatString,...)
    Definition: debugdiagnostics.h:204
    maxon::Int32 Int32
    Definition: ge_sys_math.h:51
    #define DeleteObj(obj)
    Definition: newobj.h:159
    #define NewObj(T,...)
    Definition: newobj.h:108
    #define iferr_return
    Definition: resultbase.h:1531
    Note
    None of these functions will throw an exception in case of an error.

    Alloc and Free

    Most complex classes of the Cinema API provide a static "Alloc" and "Free" function. These functions have to be used to create new instances of these classes.

    // This example allocates a BaseObject with BaseObject::Alloc().
    // If the object cannot be inserted into a document it will be deleted.
    BaseObject* cube = BaseObject::Alloc(Ocube);
    if (cube == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    if (doc == nullptr)
    {
    BaseObject::Free(cube);
    return maxon::NullptrError(MAXON_SOURCE_LOCATION);
    }
    doc->InsertObject(cube, nullptr, nullptr, true);
    #define Ocube
    Cube.
    Definition: ge_prepass.h:1118
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:69
    const char * doc
    Definition: pyerrors.h:226
    Note
    It is recommended to use AutoAlloc (see below) as much as possible to avoid memory leaks.

    AutoAlloc

    AutoAlloc is a smart pointer that allocates and deallocates a new instance of a class using its static "Alloc" and "Free" functions based on scope.

    • AutoAlloc::AutoAlloc<T>(): AutoAlloc constructor. Will call the static "Alloc" function to allocate a new object.
    • AutoAlloc::~AutoAlloc(): AutoAlloc destructor. Will call the static "Free" function of the stored object.
    • AutoAlloc::operator TYPE *(): Returns the pointer to the stored object.
    • AutoAlloc::operator TYPE &(): Returns the reference to the stored object.
    • AutoAlloc::operator->(): Returns the internal pointer. Used to access member functions and variables of the stored object.
    • AutoAlloc::operator&(): Returns a pointer to the internal pointer.
    • AutoAlloc::Release(): Returns the internal pointer and releases the ownership.
    • AutoAlloc::Free(): Frees the stored object.
    • AutoAlloc::Assign(): Sets the internal pointer to the given pointer.
    Note
    There is only a limited number of AutoAlloc constructors. If no available constructor fits use the class' "Alloc" function and manage the ownership with AutoFree.
    // This example allocates a BaseObject with AutoAlloc.
    // If something goes wrong one can leave the function and AutoAlloc will free the BaseObject.
    // If everything goes right the ownership of the BaseObject is handed over
    // to the given BaseDocument.
    AutoAlloc<BaseObject> cube { Ocube };
    if (cube == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    cube->SetName("The new cube"_s);
    // if something is wrong, just return
    if (doc == nullptr)
    return maxon::NullptrError(MAXON_SOURCE_LOCATION);
    // release ownership and insert into the document
    BaseObject* const releasedCube = cube.Release();
    doc->InsertObject(releasedCube, nullptr, nullptr, true);

    AutoFree

    AutoFree is a smart pointer that deallocates the stored object with its static "Free" function based on scope.

    • AutoFree::AutoFree(): AutoFree constructor
    • AutoFree::~AutoFree(): AutoFree destructor. Will call the static Free() function of the stored object.
    • AutoFree::operator TYPE *(): Returns the pointer to the stored object.
    • AutoFree::operator TYPE &(): Returns the reference to the stored object.
    • AutoFree::operator->(): Returns the internal pointer. Used to access member functions and variables of the stored object.
    • AutoFree::operator&(): Returns a pointer to the internal pointer.
    • AutoFree::Release(): Returns the internal pointer and releases the ownership.
    • AutoFree::Free(): Frees the stored object.
    • AutoFree::Set(): Sets the internal pointer to the given pointer.
    • AutoFree::Assign(): Sets the internal pointer to the given pointer.
    // This example allocates a BaseObject with BaseObject::Alloc().
    // The ownership is given to an AutoFree object that
    // will delete the object when the scope is left.
    BaseObject* const cube = BaseObject::Alloc(Ocube);
    if (cube == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    // AutoFree takes ownership
    AutoFree<BaseObject> cubeFree;
    cubeFree.Assign(cube);
    cubeFree->SetName("The new cube"_s);
    // if something is wrong, just return
    if (doc == nullptr)
    return maxon::NullptrError(MAXON_SOURCE_LOCATION);
    // release ownership and insert into the document
    BaseObject* const releasedCube = cubeFree.Release();
    doc->InsertObject(releasedCube, nullptr, nullptr, true);

    Further Reading