Slashdot Mirror


Memory Checker Tools For C++?

An anonymous reader writes "These newfangled memory-managed languages like Java and C# leave an old C++ dev like me feeling like I am missing the love. Are there any good C++ tools out there that do really good memory validation and heap checking? I have used BoundsChecker but I was looking for something a little faster. For my problem I happen to need something that will work on Windows XP 64. It's a legacy app so I can't just use Boosts' uber nifty shared_ptr. Thanks for any ideas."

21 of 398 comments (clear)

  1. um by Anonymous Coward · · Score: 5, Informative

    boost::shared_ptr is not a memory checker, it's a reference-counted smart pointer, and works fine in legacy apps (such as compiled under VC++ 6).

    1. Re:um by bhsurfer · · Score: 4, Insightful
      The first thing I was told by my boss when I got hired was "You're going to look at this app and want to rewrite it from scratch. Don't do it, that's not what we want you for." Software doesn't need to be pretty, you just make improvements as you can and leave the ugly but solid code alone until necessary. It's an extremely rare situation to have the luxury of a complete redesign/rewrite.

      I guess that's a long way of saying "I agree completely with what you just said."

      --
      Those are my principles, and if you don't like them... well, I have others.
      Groucho Marx
    2. Re:um by joto · · Score: 4, Insightful

      If its ugly its not solid. Ugly code is hard to understand at first glance, and its easy to introduce an error. Or do you consider code that's easy to make a mistake with as actually being "maintainable"?

      You are confusing two aspects here. Ugliness does limit maintainability. But it does not limit "solidness". "Solidness" would mean that the code actually works, and has a proven track record, such as being used in production for over 20 years. Code that has been in production for over 20 years is usually both solid and ugly.

      That ugly code is usually a monument to the "there's not enough time to do it right, but there's always enough time to do it over ... and over ... and over" and "ship it now - fix it later."

      Or it could be a monument over "the world is a complex place, and if you change anything here, and it causes the program to fail in some weird special case, your company is going to loose umpteen zillion dollars". While the reality is probably somewhere in between, rewrites should still be avoided like the plague. However, if you really have taken the time to understand what some nasty bit of code does, there's nothing wrong about cleaning it up. But most of the time, the ugly code is there for a reason.

  2. Fluid Studio's Memory Manager (MMGR) by Rezonant · · Score: 5, Interesting

    Yep, Paul Nettle's little memory manager rocks. It WILL find leaks in your program. http://www.paulnettle.com/ (Yes, you have to navigate through a horrible flash site to get it, but it's worth it).

  3. Re:two points by Anonymous Coward · · Score: 5, Informative

    Boehm's garbage collector is used in Inkscape -- and they did gradually introduce its use, so you can start using it for some things and gradually extend the usage.

    Boudewijn

  4. STLPort by kazade84 · · Score: 4, Informative

    I know this isn't exactly what the article is looking for. But, if you are using the STL (which you SHOULD be!) you may be interested to know that the STLPort STL implementation includes a debug mode which contains loads of error checking to make sure you aren't misusing STL.

    1. Re:STLPort by Chris_Jefferson · · Score: 4, Informative

      Actually, yes they do. In g++ use " -D_GLIBCXX_DEBUG ", in VC++ enable debugging. You'll get all these errors and more. I don't understand why everyone seems to know this part of stlport and don't realise other librarys have it as well.

      --
      Combination - fun iPhone puzzling
  5. Re:two points by Anonymous Coward · · Score: 4, Informative

    gcc 4.2 includes a good part of tr1 as was released (late) a few weeks ago.

    shared_ptr is a blessing and a curse. It saves you from manually destructing objects held in a collecton (good) but too many developers use it for lifetime management (bad).

  6. You are looking for PageHeap by Photo_Nut · · Score: 4, Informative

    PageHeap is a debugging tool for Windows created by Microsoft. It does what you want.

    For more information look here:
    http://support.microsoft.com/kb/286470

  7. Valgrind by bms20 · · Score: 5, Informative

    Use valgrind : www.valgrind.org It is (in my opinion) the best tool available for this purpose. In fact, I develop C++ exclusively on linux first because of valgrind, then port to Win32 later. By the way, you're not missing out on anything special by not programming in Java or C#. Both of those languages are slow, and introduce their own language complexities. -bms20

  8. Re:Boost? Ugh by pzs · · Score: 5, Interesting

    I would be inclined to agree with this. I used the Boost Graph Library for some research code a few years ago. It's been designed to be extremely generic, which although a good thing sometimes makes it pretty difficult to just start coding something without all the bells and whistles. For operations on graphs, such as walking through, you can use their specialised functions for doing things but it takes days and days to work out how to use them and I ended up just using regular loops because they were much easier to understand.

    Getting it to compile was a bit of a nightmare too. It has its own native compilation management tool that you have to download as well. What the hell is wrong with using make like everybody else? It also uses a very complex template hierarchy that produces terrifying error messages.

    I'm sure that once you become an expert, BGL is really powerful and efficient, but I found the learning curve too steep. I just want to get in and build a working prototype quickly so I can see what I'm doing, not spend hours wading through manuals and examples to build the simplest program.

    I'll be with the parent post and get modded a troll by boost developers.

    Peter

  9. eFence by cannonfodda · · Score: 4, Interesting

    I haven't used it for a while, but I used to use Bruce Peren's efence for bits of malloc debugging, it hasn't been actively developed for ages but it's pretty light weight if that's what you need. There appears to be an up to date branch DUMA which I haven't tried. As far as I remember you can use efence under WIN and DUMA claims to work......

    Unfortunately, what you prolly want is valgrind or purify.

    --
    Hmmmmmm
  10. Re:Duh! by WrongSizeGlass · · Score: 4, Funny

    Replace new/delete, malloc/free, whatever/whichever, with your own tracking version. In the end you may come out with an even better idea of memory handling for whatever you are working on at the time. God-awful simple you idiot !! You disgust me that you are so stupid !! Just replace that post with your own comment system, such as replacing God-awful with I'm, idiot with smart, disgust with inspire and stupid with curious.
  11. Re:Boost? Ugh by Viol8 · · Score: 4, Insightful

    "you'd better get used to the "weird syntax" of templates and especially the boost libraries"

    I'm used to templates syntax (though I think its ugly and Stroustrup could have done a lot better) but Boost makes it worse by overloading operators and then using them in ways never intended that produce syntax that a plain C++ wouldn't even recognise, never mind understand what its doing.eg the gratiutous overload of () for matrix ops where a simple function call would have been much cleaner and easier to follow.

  12. Re:I've used... by TapeCutter · · Score: 4, Informative

    If you use MS compilers the memory debug stuff is in crtdbg.h, IIRC it has been there in one form or another since V1.5 but for some reason seems too obscure for the average Windows programmer to find. ;)

    It is a very handy feature for finding leaks, buffer overflows, ect. The only other product I've used to find memory problems on recent incarnations of Windows is Purify. The MS solution is infinitely simpler because it's built into the environment and it's narrowly focused on memory problems. To state the obvious and in fairness to Purify, MSDev is infuriatingly fussy when it comes to building debug modules for IBM's Purify.

    --
    And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
  13. Most people can't understand Purify's output by Anonymous Coward · · Score: 5, Insightful
    Most people can't understand Purify's output, and I've actually ran across coders who actually believe their code can't be as bad a Purify says it is.

    For example, this code has serious issues:

    extern string method_that_returns_string_object();
    char *ptr;
          .
          .
          .
    ptr = method_that_returns_string_object();
          .
          . . That actually will compile, and seem to "work". But it's horribly wrong, and Purify will find the problems.

    And FWIW, I've used Purify on massive apps, and found huge problems that the developers didn't even know were there. On one project, they couldn't explain why their "perfect" app kept crashing, either. Worse for them, I had been hired as a consultant to fix their problems that they couldn't seem believe existed (HINT: your boss hired someone from the outside...), and after watching the team flail and spend literally almost a man-year trying to find one memory bug, I finally had enough of "advice giving" being ignored and got on their system, linked their app under Purify, ran it, and found the bug - a double delete of an object from two different threads. It all took me about fifteen minutes. I did that in front of their management. I made my point.

    Purify (and like tools) are a great help. Not using them is like trying to build a house without power tools. Yeah, it can be done. But what would you think if hired a builder to make your house and his team showed up carrying hand saws? Oh, and you are paying that team to hand-saw all the lumber...

    What would you think of that builder?

    Yet, when a developer asks for tools like Purify, management often balks. Because 1) they're shortsighted, and 2) developers don't know how to use such tools.

    Like I said - what would you think of a construction company where the workers don't know how to use modern power tools to help their productivity?

    Well, you just put yourself in that category.

    Yes, Purify is somewhat slower than running without Purify. But it's a lot faster than most other full-memory checking methods. If you're worried about speed, link against the Win32 debug libraries - they'll at least show problems with double free() calls, access of free()'d and deleted objects, etc. And without too much performance problems.
  14. Don't allocate or free = no leaks = need no tools by seniorcoder · · Score: 5, Insightful

    We are running many high speed financial message processing applications. A crash for any reason (including a leak) would be very costly for us.

    We pre-allocate pools of objects at startup and then re-use them. No other memory is allocated or freed while the process is running. Our pools of reusable objects are monitored very carefully as an object that isn't release back to its pool when the job is done is akin to a memory leak. Use of sentries to automatically release objects back to the pools when they fall out of scope is mandatory.

    So my answer is to the problem is:
    1. Use sentries (or some other mechanism) to guarantee memory is released.
    2. Don't allocate except at startup.
    3. No need for elaborate tools due to the above.

    I'm sure that not all applications data usage would fit into this model, but it is surprising how many can.

    We have seen some leaks in our applications. These were tracked down to STL internally leaking. They weren't generally very large and therefore we continue to live with them.

    On the subject of garbage collectors, some of our colleagues use Java and .NET. Both sets of colleagues have had major performance problems caused directly by the garbage collectors kicking in and consuming vast CPU power while they did their thing. The result was a failure to process messages in a timely manner in our high speed environment. The solution in both languages was to use pools of reusable objects and never cause their reference counts to drop to 0. Thus they implemented the very same mechanism that we use in C++ and avoided the garbage collectors.

    So don't think that a garbage collector is the solution. Perhaps in less demanding applications it is a potential answer.

    Lastly, I strongly dislike anything from Rational. I find them overpriced unreliable bloatware (YMMV). Purify used to be good some time ago, but those days are long gone.

    I echo what others have said above. You are a developer. You know your requirements. Build a simple tool to monitor and check your usage. For us it was managed pools of re-usable objects.

  15. Re:I've used... by inviolet · · Score: 5, Funny

    Memory checkers? GARBAGE COLLECTORS?! Have you no HONOR?!

    We are KLINGON. We need no checkers. We need no garbage collectors. We need none of these weak HUMAN facilities. We write our CODE from the COMMAND LINE:

    > COPY CON DECAPITATOR.EXE
    [Alt+077] [ALT+090] . . .

    --
    FATMOUSE + YOU = FATMOUSE
  16. Re:two points by d00ber · · Score: 4, Informative

    Also, shared_ptr has been promoted to the draft standard C++-0x so you can use std::shared_ptr.

    You'll be able to use C++-0x in gcc-4.3 with a switch.

    I also heard that std::auto_ptr is being deprecated (not removed) I guess in favor of rvalue references.

    Finally, there is a motion to include garbage collection in the C++ language. This is sponsored by none other than Hans Boehm among others.

    I realize this doesn't help immediately.

  17. Re:Most tools I've tried are useless by peterpi · · Score: 4, Insightful

    I didn't explain it all that well. What I mean is; I love destructors.

    A good example of what I'm talking about is a std::ifstream versus a java.io.FileInputStream. If you make an ifstream on the stack, you can be absolutely certain that when it goes out of scope, the destructor will be called and the file closed. You can be certain that it will happen, and you can also be certain when it happens; at the very point it goes out of scope.

    With a heap based FileInputStream, you have no such gaurentee. You leak it, and you just hope that the finaliser gets called soon (if at all). I've had more than one occasion where I've been leaking FileInputStreams quicker than the garbage collector cares to clean them up, and sooner or later the OS says 'no' and you get an exception. And it's very difficult to reproduce, because it's all down to the whim of the garbage collector, and you always go slower when you're looking for a bug.

    Of course the answer to this is to say "Well you should Close() your input stream beforehand". But that's just as bad as saying "You should delete your heap based objects" in C++. It's that situation of having to manually shut down objects that seems old fashioned to me.

    Maybe there's a better way these days, I've been away from Java for a couple of years now.

    (I do enjoy coding in either language though!)

  18. Re:two points by Anonymous+Brave+Guy · · Score: 4, Insightful

    It's not automatically bad, but using semi-automated memory management like this tends to reduce the emphasis on constructing things only when they're needed and destroying them immediately when you're done with them. This concern, known as "Java bloat syndrome" in honour of the language that first popularised it, can lead to major performance problems in applications that manipulate a lot of data, and is a favourite mistake made by the cult of "hardware is cheap, so optimisation doesn't matter".

    The thing is, this sort of care-free programming philosophy is natural in languages like Java, so languages like Java have had to learn from their early mistakes and adapt. There have been dramatic improvements in GC technology since those early days, and today there isn't the same degree of performance penalty associated with relying on GC to clear everything up.

    However, this sort of behind-the-scenes magic isn't really the "C++ way". You can do it, but tools like shared_ptr don't have the same level of sophistication as full-blown GC. Using them requires some care from programmers, and as the grandparent post said, this can lead to problems if the programmers come to rely on them more than they ought.

    FWIW, I'm not sure I'd have described things in quite such black-and-white terms as the GP, but I can see the underlying point and I think it's a valid one.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.