views:

1010

answers:

5

I'm still trying to debug a very sneaky memory corruption problem. I came across a section of my code that allocates memory on one thread and deletes it on another.

I have a vague feeling that this is wrong, but I'm not sure why. The threads share the process memory and access to these structures is protected by a mutex, so I think everything would work. However, is it there any danger I'm not seeing?

A: 

The danger is that multi-threaded code is harder to write. However, if the program is correct then there should be no problem. This is probably a common occurrence in producer/consumer patterns where the producing thread allocates memory that is placed in a synchronized queue and released by a consuming thread.

Judge Maygarden
A: 

As long as the allocation and deallocation of the memory are properly protected and you also ensure that the structures are only accessed while they are under the same mutex, I can't really see this being a problem. Please note that this goes for read and write access, not only for write access as you need to ensure that the structure stays where it is while someone's reading data from it.

Is there are chance that some code somewhere attempts to access these data structures outside mutex protection? Or worse could there be a chance that some of these structures fall victim to C++ object lifetime considerations (say, they're being destroyed because they're referenced via boost::shared_ptrs and the last shared_ptr has just exited the building?

Are you 100% sure that it is memory corruption? Another bug that looks very similar is when some code holds onto a reference that it shouldn't and the referenced object gets moved due to memory reallocation. This isn't such an outlandish scenario as adding another element to a vector can trigger that (just to give an example).

Timo Geusch
There is no strict requirement for mutex protection when accessing the object as long as only one thread "owns" the pointer to the object at a time. For example, in the producer/consumer model mentioned in another answer
Tall Jeff
+5  A: 

As indicated in another answer by @monjardin, there is nothing inherently wrong with what you are trying to do.

As an additional thought, you didn't mention the platform, etc. you are running into this problem on but if multi-threading is new to you and/or this application you are working on, you want to be sure that the standard support libraries you are using are the thread safe versions of the libraries. In many environments/platforms they have both the single threaded and multi-threaded versions of the support libraries available to the developer. If you are using threads but linking against the single thread version of the libraries, lots of bad things could be happening. For example, in a single threaded support library for malloc() and free() it would not have mutex protection for the heap (as an optimization). The multi-thread version of the library would add mutex protection to the heap manager to support more than one thread manipulating the heap at a time. (This is just one example).

Tall Jeff
A: 

Nope, This is fine, and quite common especially with windows programming using CreateThread, where you might allocate the arguments on the heap, and pass the argument as the a void * argument to CreateThread. And the easiest thing to do is to let the called thread delete it's arguments when it's done with them. However if you are having memory corruption issues, and you are concerned about having one thread delete memory that another created, perhaps you should consider if there is a double delete happening, say if the transfer of what context is now responsible for cleaning up the allocated memory is not clear, perhaps both calling and called section are doing it?

Dan
+1  A: 

remember that the memory manager itself has to be thread-safe too, not only your use of the memory. check your platform docs.

Javier