If you do multithreaded programming, you really want to be reference counting.
I realise the subset of people who stumble across this blog and who are writing in C/C++ is possibly a minority. I realise that the number of those who do multithreaded work is probably a minority again. Nevertheless, if you are one of those people, heed these words.
Memory management.
Yes, it’s a horrible, horrible thing. There are two ways to do memory management in multithreaded applications in C/C++:
- Dynamically-allocated objects are always allocated and de-allocated by the same thread and that thread is guaranteed to perform the allocation/de-allocation while no other thread is trying to access those objects; or
- you atomically reference-count objects
You can mix and match in one direction, but never ever think you can do it the other: that is, you can reference-count objects even if you know they’ll only ever be de-allocated by the thread that allocated them (because it lets you pass them between threads with impunity), but don’t think that you can play fast and loose with memory allocation. In any sufficiently-large application, you will lose track of which threads are tracking which objects, and there’s a good chance you’ll get to the point where you realise you need reference counting just so that you have a mechanism for saying “all threads have finished with this string, get rid of it”—otherwise, you’ll end up implementing something sorta kinda like referencing counting, but not.
So basically, my advice boils down to this:
Reference-count your objects.
If you really want to, you could write reference-counting wrappers around malloc and free for allocating arbitrary blocks of memory. In C++, extend everything from a base class which implements a pair of methods that do it for you. Get into the habit of “retaining” objects when you’re passed them. Microsoft got this right with COM. NeXT (then Apple) got this right with OPENSTEP/Cocoa.
Just do it. You’ll thank me one day.