Related
I'm currently working on a project requiring per thread storage for caching fetched data. I'm looking into boost::thread_specific_ptr for solution, but I'm still not very clear on the following aspects:
Where is that object thread_specific_ptr pointed to actually allocated in process address space? Are those in special segments like bss, data or others? Will that be protected so that any other threads in the same process could not examine the address where the object is located? If it is a special memory section, will it be dangerous to use STL containers in boost::thread_specific_ptr since it could auto resize itself when more data is added till crossing the section boundary?
Thanks in advance!
The thread-local pointers are platform dependent, but the object you store via it is just on the heap.
The only thing really thread local is a pointer to it, and the operating system/runtime library will have some thread-associated storage to keep them in. That's an implementation detail, and you don't have to worry about it.
If you plan on storing a lot of containers, consider storing one structure that contains (pointers to) them all.
Also, use thread-local storage sparingly. Depending on them is a design smell in my book. You might simply require process isolation, instead of threads.
I am currently writing a library that parse some structured binary data into a set of objects. These objects are expected to outlive any user code, and would normally be freed at the end or after the main function.
I am using shared (and weak) pointers to manage the memory of each object, but it is causing a lot of added complexity to the program, and raises structural issues that I will not get into in this particular question.
Considering that:
traversing the entirety of the binary data is expensive and I cannot afford to do it more than one time,
each visited entry is used to build an object, that then gets registered (i.e. added into the set),
entries in the binary data may rely on other entries that appears later but gets parsed immediately, and registered when the entry is visited again,
duplicate entries may appear at any moment, but I need to merge those duplicates into one instance (and update any pointer referencing those duplicates to the new merged entry) before registration,
every single one of those objects is guaranteed to be of one of many POD types deriving a common class, so nothing except memory needs to be cleaned up,
the resulting program will run on a modern OS (or in this case, that collects memory from dead processes),
I am very tempted to just use raw pointers, never free the memory taken by those objects and let the OS do its cleanup after the process exits.
What would be the best course of action?
If you're writing reusable code, you need to at least provide the option of cleaning up. What if some program uses your library for one operation, and then continues running? It's not safe to assume that the process exits immediately after your library's task is complete.
The other answers cover the general and standard approach: in an ideal world, yes, you'd clean up your memory, because it makes the code more generic and more reusable and helps with tooling. As others have said, std::unique_ptr for owning pointers and raw pointers for non-owning pointers should work well.
There are a couple of more specialized approaches that may or may not be useful:
Use a pool allocator (such as Boost.Pool, or roll your own) to allocate a bunch of memory up front then dole out pieces of it for your objects. You can then free every object at once by deleting the pool.
Intentionally not freeing memory is occasionally a valid technique. See, e.g., "Increasing Compiler Performance by Over 75%", by Walter Bright. Of course, a compiler is a specialized problem domain, and Walter Bright is probably one of the top compiler developers alive, so techniques that work for his problem domain shouldn't be blindly applied elsewhere.
the resulting program will run on a modern OS (or in this case, that collects memory from dead processes)
I am very tempted to just use raw pointers, never free the memory taken by those objects and let the OS do its cleanup after the process exits.
If you take this approach, then anyone who uses your library and then uses valgrind to try to detect memory leaks in their program will report massive leaks coming from your library and complain to you about it, so if I were you I definitely would not do this.
If you are writing a library then you should provide a cleanup function that frees all memory that you allocated.
A practical example of why this is useful is if a Windows DLL uses your library. When the library is loaded, static data is initialized. When the library is unloaded, static data is cleared. If your library has some global pointers to memory that is never freed, then load-unload cycles of the DLL will leak memory.
If the objects are all of the same type, then rather than allocating each one independently, you could just put them all into a vector and have them refer to each other by index number instead of using pointers. The vector's built-in memory management takes care of allocating space as needed, and when you're done with the objects, you can just destroy the vector to deallocate them all at once. (Note that vector::clear() doesn't actually free the memory, though it does make it available to store a new set of objects in the vector.)
If your objects aren't all the same type, you'll want to look into the more general concept of region-based memory management. As above, the idea is that you can allocate all your objects in a relatively small number of memory chunks (possibly just one), which can be freed later without having to track all the
individual objects allocated within.
If your ownership and lifetimes are clear I suggest you use unique_ptr for the owning pointers and raw pointers for the non-owning pointers. It should be less complex than shared_ptr and weak_ptr whilst still managing memory automatically.
I don't think not managing memory at all is an option. But I think using smart pointers to express ownership is not just about good memory management it also makes code easier to reason about.
Try to think of future maintenance work. Suppose your code needs to be broken up or other stuff done after it. In this case you're opening yourself up to leaks or being a resource hog later down the line.
Cleaning up (or being able to do s) is good. It may seem obvious now that an application should work with a single structured binary dataset throughout its entire lifetime, but you'll start kicking yourself once you realize you need to write an application that needs to reset half-way through and start over with another dataset.
(a related thing that's easy to overlook is that an application may need to work with two completely independent datasets at the same time, so try not to design your library to exclude that use case!)
That said, I think you may be focusing too much on the extremes. Code that shouldn't participate in memory management can use raw pointers, and this is reasonable when there is no risk of these pointers outliving your structured dataset in memory.
However, that doesn't mean that code that does participate in memory management needs to use raw pointers too. You can use smart pointers to manage your data structures even if you are passing raw pointers out to the user.
That aside, keep in mind that, in my experience, pointers are usually the wrong semantics — usually, most use cases are most natural with reference or value semantics, which means you should be passing around raw references, or passing around lightweight wrapper class that have reference or value semantics, but are implemented as containing a pointer to the actual data. Or even as a copy of the actual data if appropriate.
I want to share data between threads, and have it automatically deleted when the last user is done with it. This seems to work, most of the time, using boost::interprocess::shared_ptr in a boost::fixed_managed_shared_memory segment: but not always.
So, is boost::interprocess::shared_ptr thread (and interprocess) -safe?
If I'm using my shared memory at a fixed address (I'm pretty certain this is going to be okay in my 64-bit (well, 48-bit) address space), is it possible to use a normal boost::shared_ptr (which are threadsafe) instead?
some clarification:
The pointer type I use is plain void*, (my shared memory is mapped to a fixed address).
The question of threadsafety is about the reference count -- i.e., whether copying/destroying shared pointers to the same thing in different processes at the same time is permitted. Not access to the same shared pointer in different threads, and not access to the pointee.
The reference count used in boost::interprocess:shared_ptr is implemented using an atomic counter defined in boost/interprocess/detail/atomic.hpp with the refcount logic mainly implemented by boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp. The intent is to have the refcount be handled in a thread (and interprocess) safe manner.
The atomic operation implementations differ depending on the specific target platform (Windows uses the Win32 Interlocked APIs, some platforms use various inline assembly, etc). It might be helpful to know what platform you're targeting. I suppose that you may be running into a bug in the refcount handling, though I wouldn't count on it.
I've restricted the above answer to the area you wanted specifically addressed:
The question of threadsafety is about the reference count -- i.e., whether copying/destroying shared pointers to the same thing in different processes at the same time is permitted. Not access to the same shared pointer in different threads, and not access to the pointee.
That said, I'd look at bugs introduced possibly by the items you mention above or by somehow creating 'independent' boost::interprocess:shared_ptr objects (where different shared_ptrs refer to the same object using different refcounts). This situation can be easy to have happen if you have some code that continues to use and/or pass around the raw object pointer.
boost::shared_ptr<T> is not interprocess safe, so whether it is multithread safe in this context is moot. (This statement assumes that BOOST_SP_DISABLE_THREADS has not been #defined for the program's operation.)
boost::interprocess::shared_ptr<T> is, in its very nature, designed to be cross-process safe, as well as multithread safe in its nature. When the last reference goes out of scope, the pointed-at object can be cleaned up. Obviously, this cleaning up happens within the bounds of the shared memory segment used for the object.
Since boost::shared_ptr<T> uses a lock-free counting mechanism at version 1.33.0 on many platforms, it is unlikely except by the remotest of chances that cross-process deletion of an object in a shared_memory segment would succeed, and does not appear to be supported functionality by the Boost maintainers.
Er. boost::shared_ptr is most definitely not thread-safe. At least not more thread-safe than e.g. std::vector. You may read a boost::shared_ptr from multiple threads, but as soon as any thread is writing a boost::shared_ptr it must synchronize with other writers and readers.
And no, you can not use it in shared memory, it was never designed to be. E.g. it uses a so called "shared count" object that stores the reference-count and the deleter, and that shared-count object is allocated by the shared_ptr code, so it will not reside in shared memory. Also the shared_ptr code (and meta data like vtables) might be at totally different addresses in different processes, so any virtual function call would also be a problem (and IIRC shared_ptr uses virtual functions internally - or at least function pointers, which leads to the same problem).
I don't know if boost::interprocess::shared_ptr is interprocess-safe, but I'm pretty sure it's not. Interprocess synchronization is pretty expensive. Having boost::interprocess::shared_ptr not do it makes it possible for the user to block accesses to shared data. That way the high synchronization cost only has to be paid once for multiple accesses in a row.
EDIT: I would expect that the usage pattern that Eamon Nerbonne refered to in his comment (which is thread-safe with boost::shared_ptr), is also OK with boost::interprocess::shared_ptr. Can't say for sure though.
"This seems to work, most of the time, using boost::interprocess::shared_ptr in a boost::fixed_managed_shared_memory segment: but not always."
If not always means that deletion don't work always:
Just use a semaphore with your thread safe container. This semaphore is not improve thread safety, but you can verify and even limit how many user use the data. If semaphore is 0, then no more user, safe delete the shared data.
If only one user there, this will be 1, so copy out the user-requested data, delete the shared container, then return with the copy.
Looking through the code in shared_ptr.hpp, and at the docs on the boost website, it would seem as though dereferencing a single instance may or may not be threadsafe depending on the second template parameter, which determines the internal pointer type to be used. Specifically,
"The internal pointer will be of the same pointer type as typename VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is offset_ptr, the internal pointer will be offset_ptr)."
And since dereferences merely return the result of get()/get_pointer() method of this class, it should probably depend entirely on that. Boost::shared_ptr will work if you want simultaneous read-only access. For write access from multiple threads, you might have to write your own wrapper modelled after offset_ptr.
As pgroke alludes to (not sure why the downvotes) the core question is whether you are accessing the same shared_ptr instance from different threads or processes.
shared_ptr (interprocess or not) does not support this scenario, and this will not be safe.
On the other hand, shared_ptr is designed to have multiple (thread-private, or protected from concurrent modification via some other mechanism) shared pointer instances point to the same object, and have different instances of these pointers to the same object be modified concurrently without issue.
::interprocess:: here is mostly a red-herring - it doesn't change the thread-safety of the pointer, just makes sure there are no internal pointers that refer to process-private memory, etc.
So which of the two cases is it?
We have a need for multiple programs to call functions in a common library. The library functions access and update a common global memory. Each program’s function calls need to see this common global memory. That is one function call needs to see the updates of any prior function call even if called from another program.
For compatibility reasons we have several design constraints on how the functions exposed by the shared library must operate:
Any data items (both standard data types and objects) that are declared globally must be visible to all callers regardless of the thread in which the code is running.
Any data items that are declared locally in a function are only visible inside that function.
Any standard data type or an instance of any class may appear either locally or globally or both.
One solution is to put the library’s common global memory in named shared memory. The first library call would create the named shared memory and initialize it. Subsequent program calls would get the address of the shared memory and use it as a pointer to the global data structure. Object instances declared globally would need to be dynamically allocated in shared memory while object instances declared locally could be placed on the stack or in the local heap of the caller thread. Problems arise because initialized objects in the global memory can create and point to sub-objects which allocate (new) additional memory. These new allocations also need to be in the shared memory and seen by all library callers. Another complication is these objects, which contain strings, files, etc., can also be used in the calling program. When declared in the calling program, the object’s memory is local to the calling program, not shared. So the object’s code needs to handle either case.
It appears to us that the solution will require that we override the global placement new, regular new and delete operators. We found a design for a memory management system that looks like it will work but we haven’t found any actual implementations. If anyone knows of an implementation of Nathan Myers’ memory management design (http://www.cantrip.org/wave12.html?seenIEPage=1) I would appreciate a link to it. Alternatively if anyone knows of another shared memory manager that accommodates dynamically allocating objects I would love to know about it as well. I've checked the Boost libraries and all the other sources I can find but nothing seems to do what we need. We prefer not to have to write one ourselves. Since performance and robustness are important it would be nice to use proven code. Thanks in advance for any ideas/help.
Thanks for the suggestions about the ATL and OSSP libraries. I am checking them out now although I'm afraid ATL is too Wincentric if are target turns out to be Unix.
One other thing now seems clear to us. Since objects can be dynamically created during execution, the memory management scheme must be able to allocate additional pages of shared memory. This is now starting to look like a full-blown heap replacement memory manager.
Take a look at boost.interprocess.
OSSP mm - Shared Memory Allocation:
man 3 mm
As I'm sure you have found, this is a very complex problem, and very difficult to correctly implement. A few tips from my experiences. First of all, you'll definitely want to synchronize access to the shared memory allocations using semaphores. Secondly, any modifications to the shared objects by multiple processes need to be protected by semaphores as well. Finally, you need to think in terms of offsets from the start of the shared memory region, rather than absolute pointer values, when defining your objects and data structures (it's generally possible for the memory to be mapped at a different address in each attached process, although you can choose a fixed mapping address if you need to). Putting it all together in a robust manner is the hard part. It's easy for shared memory based data structures to become corrupted if a process should unexpectedly die, so some cleanup / recovery mechanism is usually required.
Also study mutexes and semaphores. When two or more entities need to share memory or data, there needs to be a "traffic signal" mechanism to limit write access to only one user.
I was recently interviewing for a C++ position, and I was asked how I guard against creating memory leaks. I know I didn't give a satisfactory answer to that question, so I'm throwing it to you guys. What are the best ways to guard against memory leaks?
Thanks!
What all the answers given so far boil down to is this: avoid having to call delete.
Any time the programmer has to call delete, you have a potential memory leak.
Instead, make the delete call happen automatically. C++ guarantees that local objects have their destructors called when they go out of scope. Use that guarantee to ensure your memory allocations are automatically deleted.
At its most general, this technique means that every memory allocation should be wrapped inside a simple class, whose constructor allocates the necessary memory, and destructor releases it.
Because this is such a commonly-used and widely applicable technique, smart pointer classes have been created that reduce the amount of boilerplate code. Rather than allocating memory, their constructors take a pointer to the memory allocation already made, and stores that. When the smart pointer goes out of scope, it is able to delete the allocation.
Of course, depending on usage, different semantics may be called for. Do you just need the simple case, where the allocation should last exactly as long as the wrapper class lives? Then use boost::scoped_ptr or, if you can't use boost, std::auto_ptr. Do you have an unknown number of objects referencing the allocation with no knowledge of how long each of them will live? Then the reference-counted boost::shared_ptr is a good solution.
But you don't have to use smart pointers. The standard library containers do the trick too. They internally allocate the memory required to store copies of the objects you put into them, and they release the memory again when they're deleted. So the user doesn't have to call either new or delete.
There are countless variations of this technique, changing whose responsibility it is to create the initial memory allocation, or when the deallocation should be performed.
But what they all have in common is the answer to your question: The RAII idiom: Resource Acquisition Is Initialization. Memory allocations are a kind of resource. Resources should be acquired when an object is initialized, and released by the object itslef, when it is destroyed.
Make the C++ scope and lifetime rules do your work for you. Never ever call delete outside of a RAII object, whether it is a container class, a smart pointer or some ad-hoc wrapper for a single allocation. Let the object handle the resource assigned to it.
If all delete calls happen automatically, there's no way you can forget them. And then there's no way you can leak memory.
Don't allocate memory on the heap if you don't need to. Most work can be done on the stack, so you should only do heap memory allocations when you absolutely need to.
If you need a heap-allocated object that is owned by a single other object then use std::auto_ptr.
Use standard containers, or containers from Boost instead of inventing your own.
If you have an object that is referred to by several other objects and is owned by no single one in particular then use either std::tr1::shared_ptr or std::tr1::weak_ptr -- whichever suits your use case.
If none of these things match your use case then maybe use delete. If you do end up having to manually manage memory then just use memory leak detection tools to make sure that you aren't leaking anything (and of course, just be careful). You shouldn't ever really get to this point though.
You'd do well to read up on RAII.
replace new with shared_ptr's. Basically RAII. make code exception safe. Use the stl everywhere possible. If you use reference counting pointers make sure that they don't form cycles. SCOPED_EXIT from boost is also very useful.
(Easy) Never ever let a raw pointer own a object (search your code for the regexp "\= *new". Use shared_ptr or scoped_ptr instead, or even better, use real variables instead of pointers as often as you can.
(Hard) Make sure you don't have any circular references, with shared_ptrs pointing to each other, use weak_ptr to break them.
Done!
Use all kind of smart pointers.
Use certain strategy for creation and deletion of objects, like who creates that is responsible for delete.
make sure that you understand exactly how an object will be deleted everytime you create one
make sure you understand who owns the pointer every time one is returned to you
make sure your error paths dispose of objects you have created appropriately
be paranoid about the above
In addition to the advice about RAII, remember to make your base class destructor virtual if there are any virtual functions.
To avoid memory leaks, what you must do is to have a clear and definite notion of who is responsible for deleting any dynamically allocated object.
C++ allows construction of objects on the stack (i.e. as kind-of local variables). This binds creation and destruction the the control flow: an objects is created when program execution reaches its declaration, and the object is destroyed when execution escapes the block in which that declaration was made. Whenever allocation need matches that pattern, then use it. This will save you much of the trouble.
For other usages, if you can define and document a clear notion of responsibility, then this may work fine. For instance, you have a method or a function which returns a pointer to a newly allocated object, and you document that the caller becomes responsible for ultimately deleting that instance. Clear documentation coupled with good programmer discipline (something which is not easily achieved !) can solve many remaining problems of memory management.
In some situations, including undisciplined programmers and complex data structures, you may have to resort to more advanced techniques, such as reference counting. Each object is awarded a "counter" which is the number of other variables which point to it. Whenever a piece of code decides to no longer point to the object, the counter is decreased. When the counter reaches zero, the object is deleted. Reference counting requires strict counter handling. This can be done with so-called "smart pointers": these are object which are functionally pointers, but which automatically adjust the counter upon their own creation and destruction.
Reference counting works quite good in many situations, but they cannot handle cyclic structures. So for the most complex situations, you have to resort to the heavy artillery, i.e. a garbage collector. The one I link to is the GC for C and C++ written by Hans Boehm, and it has been used in some rather big projects (e.g. Inkscape). The point of a garbage collector is to maintain a global view on the complete memory space, to know whether a given instance is still in use or not. This is the right tool when local-view tools, such as reference counting, are not enough. One could argue that, at that point, one should ask oneself whether C++ is the right language for the problem at hand. Garbage collection works best when the language is cooperative (this unlocks a host of optimizations which are not doable when the compiler is unaware of what happens with memory, as a typical C or C++ compiler).
Note that none of the techniques described above allows the programmer to stop thinking. Even a GC can suffer from memory leaks, because it uses reachability as an approximation of future usage (there are theoretical reasons which imply that it is not possible, in full generality, to accurately detect all objects which will not be used thereafter). You may still have to set some fields to NULL to inform the GC that you will no longer access an object through a given variable.
I start by reading the following: https://stackoverflow.com/search?q=%5Bc%2B%2B%5D+memory+leak
A very good way is using Smart Pointers, the boost/tr1::shared_ptr. The memory will be free'd, once the (stack allocated) smart pointer goes out of scope.
You can use the utility.
If you work on Linux - use valgrid (it's free).
Use deleaker on Windows.
Smart pointers.
Memory management.
Override 'new' and 'delete' or use your own macros/templates.
On x86 you can regularly use Valgrind to check your code