Freeing memory: why, when and how ?

Roald Baudoux's icon

I don't understand in which cases freeing memory upon object deletion is necessary or not.

In Ichiro Fujinaga's tutorial, code for most objects do not have any free() method at all. In the SDK the code often includes it but in many cases it includes only an empty line ending with a semicolon.

So:
1. Is the object deletion (whatever the cause is: deleting the object from patch, closing the patch, quitting Max) the only situation where memory should be freed ?
2. Could a free() method containing no code always be replaced by a '0L' argument in object's main() method ?
3. In which situation(s) is a free() method with non-bogus code necessary ?
4. What should be removed from memory ? Every parameter defined in the initial struct ? Something else ?

Thank you in advance.

Roald Baudoux's icon

Thanks Nicolas ! Gonne make a tour to Stackoverflow.com.

Peter Castine's icon

To (perhaps) clarify over and above Nicolas's post:

Max will free up your object struct (which it knows about) whenever your object is deleted (closing the patch, deletion from the patch during editing, anything else). You told Max the size of your struct in your call to class_new() [or the old-school, and probably now-deprecated, setup()] but that is all.

It is *your* responsibility to free up any and all memory you allocated yourself. You don't have to worry about the object itself [allocated with object_alloc() or newobject()]. As previously stated, Max knows how much memory your object's struct has. But anything that you allocated with getbytes(), malloc(), or anything similar, is your responsibility. Max cannot magically keep track of all your getbytes() and malloc() calls for you.

You don't need to worry about inlets and outlets, because Max maintains a linked list of these as you create them with inlet_new(), outlet_new(), and related shortcut friends (intin(), floatout(), etc.) inside the t_object component (first element of your object's struct). Proxies are your responsibility.

Memory allocation mostly happens in your new method, but some objects may allocate additional memory over the course of their lifetime. Your job to keep track of this.

If you don't allocate any heap memory in the course of your object's lifetime, then it is perfectly safe to pass NULL for the free function in your call to setup(). If you pass NULL, Max will not call the function at object deallocation time (If it did, about a gazillion existing objects would immediately crash Max every second of the day).

The exception to the last paragraph are MSP (and, IMS, Jitter) objects, where you *must* have a real free function. In the case of MSP objects, the free function must, at a minimum, call dsp_free(), to deallocate stuff that was allocated by dsp_setup() in your new function. If the only thing you need to call in your free method is dsp_free(), you can simply pass the address of dsp_free() as your free function in your call to class_new() and the world will remain in order.

This is all in the SDK documentation. Yes, it is dense and not everything is optimally explained in the place where you might look for it. But it is there.

Roald Baudoux's icon

Thanks Peter. Well, all of this might be in the documentation but the only place specifically and explicitly dedicated to that matter ("Memory allocation") is quite short and the matter certainly deserves more.

Peter Castine's icon

You're right Roald, this really ought to get some documentation in the "Anatomy of a Max Object" section, but doesn't.

There is a bit more in the "Anatomy of an MSP Object" section, which specifically discusses the idiosyncrasies involved with dsp_free(). Then the special sections on UI objects, Atom Arrays, Jitter, etc., you get a few details more. With that, and then the sample code (and probably a bit of badgering DDZ about 15 years ago), I was able to piece together what one needs to know. Having worked with a couple of other plug-in environments helps, because they're all pretty similar with memory management.

Does anyone know who's maintaining the SDK documentation nowadays? I would give whomever a shout-out about this.

BTW, Ichiro Fujinaga wrote some useful tutorials, and there's now Eric Lyon's book on writing Max externals. Both will cover the memory management business more thoroughly.

Roald Baudoux's icon

Is there other Fuginaga's tutorials besides "Max/MSP Externals Tutorial" ? By the way I have Eric Lyon's book too but have just begin reading it.