The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Cross-thread new/delete

Suppose I have one thread allocate an instance of an object with operator new.  Is it OK for another thread to delete it?  Assume that I am linking against the multi-threaded versions of the runtime on Windows.

Under these circumstances, don't calls to the heap get serialized?  Couldn't this be a performance killer in some circumstances?

Tuesday, November 28, 2006
You can allocate and delete from different threads no problem, just make sure you use the MT runtime. As to how it's serialized internally, I don't know.
Tuesday, November 28, 2006
As I recall from reading Inside Windows NT, there's only one heap created per process by default, that's why I'm assuming that calls to the memory functions must be serialized in some way internally.  The reason that this is a problem is that it potentially has the side effect of serializing the threads in that portion of the code. 

However, it occurred to me that so long as the alloc/dealloc parts are taking little time compared to other operations that my workers are doing, this may not be a problem.

Any other comments from the real world would be helpful.
Meganonymous Rex Send private email
Tuesday, November 28, 2006
Yes, you can do it.  It will be a performance issue if you're doing lots of new/delete compared to the other work in your threads.
Mike S Send private email
Tuesday, November 28, 2006
The performance penalty really depends on the implementation of new/delete.  There's going to be some locking at some point as the internal (to the runtime) structures are updated.  But you're going to pay this price even if the allocation and deallocation occur in the same thread, as long as you're using the MT runtime.
I wouldn't worry about it until the profiler tells you it's a problem.
bmm6o Send private email
Tuesday, November 28, 2006
One thing to watch out for is the possibility of new & delete being done from different heaps, which is possible w/MSVC if your app is built as exe + one or more dll's (if exe and dllare built w/different settings for debug & release, for instance).

If you care about this (and you may not), a good discussion is at
BillT Send private email
Wednesday, November 29, 2006
Good point, we ran into the EXE/DLL issue here at work.  Without reading the article (which I will do) I think the main way to get around this is to make sure to link to the DLL version of the runtime (and the same version-- so debug builds should link to the Debug DLL, and release builds the Release DLL).

My understanding is that if you link to the static (non DLL) version of the runtimes, each module gets its own set of heap management data structures meaning that memory allocated in, say, the DLL, can't be freed by the exe.

This is probably why so many third-party API DLLs are handled-based instead of relying on the caller to delete or free buffers- having a handle-based API forces you to pass the object back to the DLL module for proper releasing of resources.
Meganonymous Rex Send private email
Wednesday, November 29, 2006
You could use either a lock-free memory manager or a memory manager that's been designed with the expectation of concurrent access. Here's a paper on a good one, with references to several others (Gnu Hoard and PtMalloc).

Or you could profile :)
Wednesday, November 29, 2006
Profile?  Why not make wild guesses, optimize prematurely, and even use inline assembler like some of my coworkers do.  Profiling is for Quiche Eaters. :)

See the following link (A favorite of my Dad's, who is a COBOL dude from back in the day.)
Meganonymous Rex Send private email
Wednesday, November 29, 2006

You may not have total control if you're building a library as a product that needs to interface to a customer's exe.  One solution is to insert "#pragma lib" statements in your include files that are controlled using #ifdef DEBUG to pull in the right libraries.  Still doesn't protect you completely, since different components can still be built w/different settings. 

The only foolproof way to do this in C++ is to use factory methods to do the allocations (while hiding the ctors), and also override operator delete to forward the delete request back to the dll that did the original allocation, as documented in the article. 

There's still a hole, though -- I haven't found any way to override operator delete[] that works.  If anyone has, I'd be grateful for info.
BillT Send private email
Thursday, November 30, 2006

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz