Goes without saying: Crash safety

Page 1 | Page 2 | Page 3 | Page 4

Memory leaks

Whenever you allocate memory, you must take care to free it after use. If you don’t do that, memory will get filled up until no more free memory is left. If that happens, further memory allocations will fail. In that case, it’s a good thing if you have Null Pointer checks in your code, as described on page 1. But still, if no memory is left, your system will freeze or crash sooner or later.

// Allocate array
Real* myRealArray = GeAllocType(Real, 4096);
if (!myRealArray) return NULL;

// ...do stuff with the array
// ...
// ..

// The array is no longer needed, we have to free it
// Allocate something
SomeClass* myObject = gNew SomeClass;
if (!myObject) return NULL;

// ...do stuff
// ...
// ..

// The object is no longer needed, we have to free it

You can make life easier by automatically freeing the allocated memory at the end of the scope, using the AutoAlloc template class.

void MyFunction()
  AutoAlloc<MyClass> myObject;
  if (!myObject) return;  // Still, don't forget the Null Pointer check

  // ...do stuff with myObject

  // Enjoy automatically freed memory at the end of MyFunction() :-)

Please note: If you plan on using AutoAlloc with your own custom class, make sure the class has the following static member functions, as those will be called internally by AutoAlloc:

class myClass
  static MyClass* Alloc()
    return gNew (MyClass*)MyClass;
  static void Free(MyClass*& pData)
    if (!pData) return;
    MyClass* d = (MyClass*)pData;
    pData = NULL;

Of course, this also works with more complex objects, e.g. CINEMA 4D objects

void MyFunction()
  AutoAlloc<BaseTag> myTag(Thermite2d, 100);
  if (!myTag) return;  // Still, don't forget the Null Pointer check!

  // ...do stuff with the tag

  // Enjoy automatically freed memory at the end of MyFunction() :-)

However, there are exceptions. If you give up the ownership of the allocated memory, you don’t have to (in fact, you must not!) free it. Examples for this situation are all functions from the API where you e.g. insert an object into a document, or a shader into a material. Another example is ObjectData::GetVirtualObjects(), which is used by all generator objects. The ownership of the resulting object is taken over by CINEMA 4D; you don’t have to care about it after you returned it at the end of the function.

For example, in the SDK documentation about BaseDocument::InsertObject(), you will see this:

BaseObject* op
Object to insert into the document. The document takes over the ownership of the pointed object.

This means that the object you inserted is now owned by the document. If the document is freed (by CINEMA 4D, or by you), the object will automatically be freed, too. Freeing it yourself could cause inconsistency in the document and might provoke a crash.

Checking for memory leaks

If you want to check for memory leaks in your plugin, you can activate the tracing feature of CINEMA 4D’s memory management. You do this by creating an empty text file called “c4d_debug.txt” and place it in your working folder. If you start CINEMA 4D in the Debugger of your IDE, the working folder will be the folder where your plugin’s binary is located. Otherwise it is the folder where the CINEMA 4D executable is located.

The c4d_debug.txt trigger file

When CINEMA 4D is run after creating that file, the C4D Debug window will appear. If there are any memory leaks, they will be listed (amongst other debug output) here CINEMA 4D.

The C4D debug console


Frank Willeke

worked with computers since more than 20 years | got hooked on computer graphics back on the AMIGA | started programming at the age of 13 | relesed some successful plugins for cinema 4d | started working for maxon computer gmbh in 2009 | now contributing to cinema 4d as a senior developer making electronic music since 1993 | playing the electric guitar since 1995 age of 14 | first live gigs in 1997 | playing the bass guitar 2005 | playing keyboards and synths since 2012 experimenting with photography since 2003

Leave a Reply

Your email address will not be published. Required fields are marked *