Freeing memory: why, when and how ?

Apr 11, 2013 at 2:46am

Freeing memory: why, when and how ?

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.

#67665
Apr 11, 2013 at 6:46am

Hi,

You always must free the memory you have allocated in the heap. That means using sysmem_newptr, malloc and such allocators but also using atomarray_new, linklist_new (more or less all functions with _new) ; most of times it is write in the API when you need to release the memory at free time. So if you allocate memory in/for your object, you need to free it when the object is freed (toto_free method is called by Max/MSP just before to destroy the object) but if you allocate memory in a function, you need to free it before to return from this function, and so…

2. Yes, i do it. But i can not say that it will ever work, as it is not confirmed nor in the API, not by cycling74 devs. To be honest i think you should provide a free function (even empty) for real coding.

3. and 4. see 1. ;-)

IMHO : You should search “Stack Heap Memory” with Google as it is something a bit messy for newbies but it is a fundamental concept you need to know for languages with no garbage collector such C. Focused your search on http://www.stackoverflow.com ; i learned a lot here.

#243446
Apr 11, 2013 at 2:19pm

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

#243447
Apr 11, 2013 at 2:44pm

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.

#243448
Apr 11, 2013 at 6:38pm

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.

#243449
Apr 11, 2013 at 10:39pm

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.

#243450
Apr 13, 2013 at 10:29am

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.

#243451

You must be logged in to reply to this topic.