tags:

views:

156

answers:

5

Note: This may sound dumb. I have an application which uses raw pointers and there are lots of memory leaks in the application.

Now my question is how easy would it be to replace the existing raw pointers with the smart pointers. And would just replacing them help is reducing memory leaks caused by not freeing dynamically allocated memory.

To explain a little further, This application is a legacy one and there are very straightforward memory leaks where memory will be allocated and wont be released in same function itself.

I have done an memory analysis using DevPartner and found many areas. Is Valgrind better than Devpartner.

+1  A: 

It depends, garbage collected programs can still have memory leaks if hard references to objects prevent the garbage collector from freeing it. If you want to figure out where the memory leaks are happening, use a profiler or write unit tests and mock objects.

Edit: To get the benefits of smart pointers, you also have to hook in or implement your own garbage collector as it's not a language feature.

Edit 2: Smart pointers apparently implement reference counting, which is a garbage collection strategy.

Gary
Smart pointers are not the same as garbage collection.
Space_C0wb0y
ah, good point. noted :-)
Gary
You don't need any garbage collector with smart Pointer, as long as you don't have cycle in your model. You just need to break the cycle with normal pointer. I used smart pointer for years and never have to implement a gc nor any memory leaks
mb14
+3  A: 

Using smart pointers would certainly be a good start to cleaning up your application, but they're not a cure-all. Lots of memory leaks could just be carelessness in an otherwise well designed program, but more likely you have significant design issues and the memory leaks are a symptom of that. When you switch to smart pointers, you still will need to make design choices like "Who owns this object," "Is ownership of this object shared between multiple clients" and "What is the expected lifetime of this object" in order to choose the proper smart pointer implementation for the given scenario. But this will be a good way to start because the process of choosing the proper flavor of smart pointer for different situations will force you to think about these things and will probably improve your design.

bshields
+2  A: 

There is no doubt that smart pointers reduce a lot of burden on the programmer w.r.t memory ownership hassles. Since you did not mention if this is a legacy application or how easy is it to change interfaces (not always required as smart pointers do degrade to raw pointers), I'd suggest that you run your application under some tool like valgrind (on Linux) or purify (on Unices and Windows) to track the memory leaks down.

From my experience, most memory leaks follow a certain pattern (developer A misses something, developer B copies that code and along with it the problem). So, using tools you might be able to solve the memory leak issues first before thinking about using smart pointers.

And if you are starting to develop this application - start with using smart pointers. They will save you a lot of time and energy down the line.

Gangadhar
A: 

Smart pointers 'document in code' ownership of objects. So for every pointer, you have to convert the 'vague document that was in some programmers head' into this 'precise document in code'. Most of the choices are easy. That still leaves alot of choices that are not. Plus in addition to ownership, you have to worry about breaking object graph cycles with weak pointers. So this overall conversion to smart pointers is not a trivial task, and if you get the cycle breaking part wrong, you will even introduce new memory leaks.

jyoung
The only thing which smart pointers document is: "I don't care who owns this object, just make sure to destroy it properly at the end". You have no idea who references the object, you also don't know when the last reference will go out of scope, so you don't know when the object will be destroyed. All in all, you have no idea about the lifetime of the object, because there is no single owner. Everybody owns the object (because every client can destroy it), so nobody owns the object. So the "ownership" is not documented at all.
Frerich Raabe
I think you are a bit confused on equating 'ownership' with 'ownership only by one object'. Most code involves (explict or implict) shared ownership. When you say (because every client can destroy it), with smart pointer no one can destroy it, just release ownership.
jyoung
@Frerich You seem to be referring to a specific kind of smart pointer, a reference counted pointer, but there are different kinds of smart pointer for different ownership scenarios. See http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm. If the flavor of smart pointer is chosen well for a given situation, it IS an excellent way of documenting the object ownership strategy in code.
bshields
@bshields: True, I thought of reference counted pointers. I should've made this explicit.
Frerich Raabe
+1  A: 

I'm going to give this a firm "very possibly".

One form of memory leak is when a function allocates memory and doesn't delete it in at least one path out of the function. Some sort of scoped pointer, like auto_ptr, might handle this very well. (Note: auto_ptr was part of the first ISO standard, and is being deprecated in the next one, so it's hard to give advice on what scoped pointer to use. Consult your compiler and library documentation to see what they support.)

Another form is where an object is allocated, and ownership is shared, meaning that there's more than one routine that uses it and no easy way to tell if everybody's through with it. This is a good candidate for shared_ptr, but you have to use some care. Assign to a shared_ptr when you create the object, and make sure that every other pointer use is a shared_ptr. If routines A, B, and C access the object through a shared_ptr, and you didn't change D, then when routines A, B, and C are through with it it goes away, regardless of D's needs.

One thing you want to avoid with shared_ptr is cycles, since if I has a shared_ptr to J, J has a shared_ptr to K, and K has a shared_ptr to I, none of those are ever going to be deleted, even if unreachable from anywhere else in the program. You need to watch for those situations. You can break them up with a weak_ptr in the cycle, or delete an element in the cycle yourself, or just live with the leak.

Another thing to consider is substituting vector and similar containers for dynamically allocated arrays and other dynamically allocated data structures. This gives you a lot of memory management for free, although you can still leak memory. If a vector grows large, and then becomes small, it will not release the extra memory. The usual practice, if you really need to reclaim memory, is to swap the once-large vector with a copy of itself.

In short, there's a lot of very useful tools to automate a lot of memory management, but they don't replace thinking on your part. A lot of issues can be solved by just turning each pointer into a shared_ptr and each array into a vector, but using those intelligently will give even greater benefits.

David Thornley