开发者

Replacing existing raw pointers with smart pointers

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 dynami开发者_运维百科cally 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.


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.


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.


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜