General guidelines to avoid memory leaks in C++ [c

2019-01-03 11:16发布

What are some general tips to make sure I don't leak memory in C++ programs? How do I figure out who should free memory that has been dynamically allocated?

29条回答
祖国的老花朵
2楼-- · 2019-01-03 11:52

If you can't/don't use a smart pointer for something (although that should be a huge red flag), type in your code with:

allocate
if allocation succeeded:
{ //scope)
     deallocate()
}

That's obvious, but make sure you type it before you type any code in the scope

查看更多
劳资没心,怎么记你
3楼-- · 2019-01-03 11:52

We wrap all our allocation functions with a layer that appends a brief string at the front and a sentinel flag at the end. So for example you'd have a call to "myalloc( pszSomeString, iSize, iAlignment ); or new( "description", iSize ) MyObject(); which internally allocates the specified size plus enough space for your header and sentinel. Of course, don't forget to comment this out for non-debug builds! It takes a little more memory to do this but the benefits far outweigh the costs.

This has three benefits - first it allows you to easily and quickly track what code is leaking, by doing quick searches for code allocated in certain 'zones' but not cleaned up when those zones should have freed. It can also be useful to detect when a boundary has been overwritten by checking to ensure all sentinels are intact. This has saved us numerous times when trying to find those well-hidden crashes or array missteps. The third benefit is in tracking the use of memory to see who the big players are - a collation of certain descriptions in a MemDump tells you when 'sound' is taking up way more space than you anticipated, for example.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-03 11:53

Great question!

if you are using c++ and you are developing real-time CPU-and-memory boud application (like games) you need to write your own Memory Manager.

I think the better you can do is merge some interesting works of various authors, I can give you some hint:

  • Fixed size allocator is heavily discussed, everywhere in the net

  • Small Object Allocation was introduced by Alexandrescu in 2001 in his perfect book "Modern c++ design"

  • A great advancement (with source code distributed) can be found in an amazing article in Game Programming Gem 7 (2008) named "High Performance Heap allocator" written by Dimitar Lazarov

  • A great list of resources can be found in this article

Do not start writing a noob unuseful allocator by yourself... DOCUMENT YOURSELF first.

查看更多
Viruses.
5楼-- · 2019-01-03 11:53
  • Try to avoid allocating objects dynamically. As long as classes have appropriate constructors and destructors, use a variable of the class type, not a pointer to it, and you avoid dynamical allocation and deallocation because the compiler will do it for you.
    Actually that's also the mechanism used by "smart pointers" and referred to as RAII by some of the other writers ;-) .
  • When you pass objects to other functions, prefer reference parameters over pointers. This avoids some possible errors.
  • Declare parameters const, where possible, especially pointers to objects. That way objects can't be freed "accidentially" (except if you cast the const away ;-))).
  • Minimize the number of places in the program where you do memory allocation and deallocation. E. g. if you do allocate or free the same type several times, write a function for it (or a factory method ;-)).
    This way you can create debug output (which addresses are allocated and deallocated, ...) easily, if required.
  • Use a factory function to allocate objects of several related classes from a single function.
  • If your classes have a common base class with a virtual destructor, you can free all of them using the same function (or static method).
  • Check your program with tools like purify (unfortunately many $/€/...).
查看更多
手持菜刀,她持情操
6楼-- · 2019-01-03 11:56

Bah, you young kids and your new-fangled garbage collectors...

Very strong rules on "ownership" - what object or part of the software has the right to delete the object. Clear comments and wise variable names to make it obvious if a pointer "owns" or is "just look, don't touch". To help decide who owns what, follow as much as possible the "sandwich" pattern within every subroutine or method.

create a thing
use that thing
destroy that thing

Sometimes it's necessary to create and destroy in widely different places; i think hard to avoid that.

In any program requiring complex data structures, i create a strict clear-cut tree of objects containing other objects - using "owner" pointers. This tree models the basic hierarchy of application domain concepts. Example a 3D scene owns objects, lights, textures. At the end of the rendering when the program quits, there's a clear way to destroy everything.

Many other pointers are defined as needed whenever one entity needs access another, to scan over arays or whatever; these are the "just looking". For the 3D scene example - an object uses a texture but does not own; other objects may use that same texture. The destruction of an object does not invoke destruction of any textures.

Yes it's time consuming but that's what i do. I rarely have memory leaks or other problems. But then i work in the limited arena of high-performance scientific, data acquisition and graphics software. I don't often deal transactions like in banking and ecommerce, event-driven GUIs or high networked asynchronous chaos. Maybe the new-fangled ways have an advantage there!

查看更多
Lonely孤独者°
7楼-- · 2019-01-03 11:57

Share and know memory ownership rules across your project. Using the COM rules makes for the best consistency ([in] parameters are owned by the caller, callee must copy; [out] params are owned by the caller, callee must make a copy if keeping a reference; etc.)

查看更多
登录 后发表回答