How do I deal with memory leaks? (2022)

These are questions about C++ Style and Technique that people ask me often. If you have better questions or comments on the answers, feel free to email me (bs at cs dot tamu dot edu). Please remember that I can't spend all of my time improving my homepages.

I have contributed to the new, unified, isocpp.org C++ FAQ maintained by The C++ Foundation of which I am a director. The maintenance of this FAQ is likely to become increasingly sporadic.

Also, the C++ Core Guidelines contains a large set of maintained guidelines for the use of modern C++.

For more general questions, see my general FAQ.

For terminology and concepts, see my C++ glossary.

Please note that these are just a collection of questions and answers. They are not a substitute for a carefully selected sequence of examples and explanations as you would find in a good textbook. Nor do they offer detailed and precise specifications as you would find in a reference manual or the standard. See The Design and Evolution of C++ for questions related to the design of C++. See The C++ Programming Language for questions about the use of C++ and its standard library.

The main point of a C++ coding standard is to provide a set of rules for using C++ for a particular purpose in a particular environment. It follows that there cannot be one coding standard for all uses and all users. For a given application (or company, application area, etc.), a good coding standard is better than no coding standard. On the other hand, I have seen many examples that demonstrate that a bad coding standard is worse than no coding standard.

Don't use C coding standards (even if slightly modified for C++) and don't use ten-year-old C++ coding standards (even if good for their time). C++ isn't (just) C and Standard C++ is not (just) pre-standard C++.

However, it is more likely that the program that you are trying to compile is poorly designed, so that compiling it involves the compiler examining hundreds of header files and tens of thousands of lines of code. In principle, this can be avoided. If this problem is in your library vendor's design, there isn't much you can do (except changing to a better library/vendor), but you can structure your own code to minimize re-compilation after changes. Designs that do that are typically better, more maintainable, designs because they exhibit better separation of concerns.

Consider a classical example of an object-oriented program:

There are three serious problems with this apparently simple idea:

Thus, the presence of "information helpful to implementers" in the base class that also acts as the interface to users is the source of instability in the implementation, spurious recompilation of user code (when implementation information changes), and excess inclusion of header files into user code (because the "information helpful to implementers" needs those headers). This is sometimes known as the "brittle base class problem."

The obvious solution is to omit the "information helpful to implemeters" for classes that are used as interfaces to users. That is, to make interfaces, pure interfaces. That is, to represent interfaces as abstract classes:

But what if there really is some information that is common to all derived classes (or simply to several derived classes)? Simply make that information a class and derive the implementation classes from that also:

Sometimes, you do want to have representation data in a class. Consider class complex:

Also, objects of a class with a virtual function require space needed by the virtual function call mechanism - typically one word per object. This overhead can be significant, and can get in the way of layout compatibility with data from other languages (e.g. C and Fortran).

See The Design and Evolution of C++ for more design rationale.

So when should I declare a destructor virtual? Whenever the class has at least one virtual function. Having virtual functions indicate that a class is meant to act as an interface to derived classes, and when it is, an object of a derived class may be destroyed through a pointer to the base. For example:

Techniques for using an indirection when you ask to create an object are often referred to as "Virtual constructors". For example, see TC++PL3 15.6.2.

For example, here is a technique for generating an object of an appropriate type using an abstract class:

If you don't override a pure virtual function in a derived class, that derived class becomes abstract:

In other words, there is no overload resolution between D and B. The compiler looks into the scope of D, finds the single function "double f(double)" and calls it. It never bothers with the (enclosing) scope of B. In C++, there is no overloading across scopes - derived class scopes are not an exception to this general rule. (See D&E or TC++PL3 for details).

But what if I want to create an overload set of all my f() functions from my base and derived class? That's easily done using a using-declaration:

Sort of, but don't do it blindly and there are often superior alternatives. Consider:

Destruction is done "derived class before base class", so virtual functions behave as in constructors: Only the local definitions are used - and no calls are made to overriding functions to avoid touching the (now destroyed) derived class part of the object.

For more details see D&E 13.2.4.2 or TC++PL3 15.4.3.

It has been suggested that this rule is an implementation artifact. It is not so. In fact, it would be noticeably easier to implement the unsafe rule of calling virtual functions from constructors exactly as from other functions. However, that would imply that no virtual function could be written to rely on invariants established by base classes. That would be a terrible mess.

Consider placement new used to place objects in a set of arenas

However, sometimes the programmer does know, and there is a way:

It is also possible to define a matching operator new() and operator delete() pairs for a class hierarchy TC++PL(SE) 15.6. See also D&E 10.4 and TC++PL(SE) 19.4.5.

Yes, but why do you want to? There are two common answers:

If there is a genuine need for "capping" a class hierarchy to avoid virtual function calls, one might ask why those functions are virtual in the first place. I have seen examples where performance-critical functions had been made virtual for no good reason, just because "that's the way we usually do it".

The other variant of this problem, how to prevent derivation for logical reasons, has a solution in C++11. For example:

These containers are homogeneous; that is, they hold elements of the same type. If you want a container to hold elements of several different types, you must express that either as a union or (usually much better) as a container of pointers to a polymorphic type. The classical example is:

So, in a sense all containers (in every language) are homogenous because to use them there must be a common interface to all elements for users to rely on. Languages that provide containers deemed heterogenous simply provide containers of elements that all provide a standard interface. For example, Java collections provide containers of (references to) Objects and you use the (common) Object interface to discover the real type of an element.

The C++ standard library provides homogeneous containers because those are the easiest to use in the vast majority of cases, gives the best compile-time error message, and imposes no unnecessary run-time overheads.

If you need a heterogeneous container in C++, define a common interface for all the elements and make a container of those. For example:

Using an Any class, such as Boost::Any, can be an alternative in some programs:

Let's look at those problems in turn. Often, a vector<X> is slower than somebody's specialized My_container<X> because My_container<X> is implemented as a container of pointers to X. The standard containers hold copies of values, and copy a value when you put it into the container. This is essentially unbeatable for small values, but can be quite unsuitable for huge objects:

The second frequently occuring genuine performance problem is the use of a map<string,X> for a large number of (string,X) pairs. Maps are fine for relatively small containers (say a few hundred or few thousand elements -- access to an element of a map of 10000 elements costs about 9 comparisons), where less-than is cheap, and where no good hash-function can be constructed. If you have lots of strings and a good hash function, use a hash table. The unordered_map from the standard committee's Technical Report is now widely available and is far better than most people's homebrew.

Sometimes, you can speed up things by using (const char*,X) pairs rather than (string,X) pairs, but remember that Intrusive lists can be really fast. However, consider whether you need a list at all: a vector is more compact and is therefore smaller and faster in many cases - even when you do inserts and erases. For example, if you logically have a list of a few integer elements, a vector is significantly faster than a list (any list). Also, intrusive lists cannot hold built-in types directly (an int does not have a link member). So, assume that you really need a list and that you can supply a link field for every element type. The standard-library list by default performs an allocation followed by a copy for each operation inserting an element (and a deallocation for each operation removing an element). For std::list with the default allocator, this can be significant. For small elements where the copy overhead is not significant, consider using an optimized allocator. Use a hand-crafted intrusive lists only where a list and the last ounce of performance is needed.

People sometimes worry about the cost of std::vector growing incrementally. I used to worry about that and used reserve() to optimize the growth. After measuring my code and repeatedly having trouble finding the performance benefits of reserve() in real programs, I stopped using it except where it is needed to avoid iterator invalidation (a rare case in my code). Again: measure before you optimize.

How do we avoid this? The simplest solution is to prevent copying by making the operations that copy private:

Now return to Point. For Point the default copy semantics is fine, the problem is the constructor:

Why would I want to change an argument? Well, often we have to, but often we have an alternative: produce a new value. Consider:

I do want to change the argument, should I use a pointer or should I use a reference? I don't know a strong logical reason. If passing ``not an object'' (e.g. a null pointer) is acceptable, using a pointer makes sense. My personal style is to use a pointer when I want to modify an object because in some contexts that makes it easier to spot that a modification is possible.

Note also that a call of a member function is essentially a call-by-reference on the object, so we often use member functions when we want to modify the value/state of an object.

In terms of time and space, an array is just about the optimal construct for accessing a sequence of objects in memory. It is, however, also a very low level data structure with a vast potential for misuse and errors and in essentially all cases there are better alternatives. By "better" I mean easier to write, easier to read, less error prone, and as fast.

The two fundamental problems with arrays are that

Since an array doesn't know its size, there can be no array assignment:

An array is of a fixed size determined at compile time:

The way that array names "decay" into pointers is fundamental to their use in C and C++. However, array decay interact very badly with inheritance. Consider:

If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, "nullptr" will be a keyword.

Basically, C++ constructs objects simply by concatenating sub objects. Thus

Virtual functions are typically implemented by adding a pointer (the vptr) to each object of a class with virtual functions. This pointer points to the appropriate table of functions (the vtbl). Each class has its own vtbl shared by all objects of that class.

Having the order of evaluation undefined is claimed to yield better performing code. Compilers could warn about such examples, which are typically subtle bugs (or potential subtle bugs). I'm disappointed that after decades, most compilers still don't warn, leaving that job to specialized, separate, and underused tools.

Because machines differ and because C left many things undefined. For details, including definitions of the terms "undefined", "unspecified", "implementation defined", and "well-formed"; see the ISO C++ standard. Note that the meaning of those terms differ from their definition of the ISO C standard and from some common usage. You can get wonderfully confused discussions when people don't realize that not everybody share definitions.

This is a correct, if unsatisfactory, answer. Like C, C++ is meant to exploit hardware directly and efficiently. This implies that C++ must deal with hardware entities such as bits, bytes, words, addresses, integer computations, and floating-point computations the way they are on a given machine, rather than how we might like them to be. Note that many "things" that people refer to as "undefined" are in fact "implementation defined", so that we can write perfectly specified code as long as we know which machine we are running on. Sizes of integers and the rounding behaviour of floating-point computations fall into that category.

Consider what is probably the the best known and most infamous example of undefined behavior:

Other examples of undefined behavior stems from the compilation model. A compiler cannot detect an inconsistent definition of an object or a function in separately-compiled translation units. For example:

Finally, we have the apparently unnecessary and rather annoying undefined behavior of individual expressions. For example:

IMO far too many "things" are left undefined, unspecified, implementation-defined, etc. However, that's easy to say and even to give examples of, but hard to fix. It should also be noted that it is not all that difficult to avoid most of the problems and produce portable code.

Note also that the definition has the desirable properties that

So why is something like Can_copy() - or something even more elegant - not in the language? D&E contains an analysis of the difficulties involved in expressing general constraints for C++. Since then, many ideas have emerged for making these constraints classes easier to write and still trigger good error messages. For example, I believe the use of a pointer to function the way I do in Can_copy originates with Alex Stepanov and Jeremy Siek. I don't think that Can_copy() is quite ready for standardization - it needs more use. Also, different forms of constraints are in use in the C++ community; there is not yet a consensus on exactly what form of constraints templates is the most effective over a wide range of uses.

However, the idea is very general, more general than language facilities that have been proposed and provided specifically for constraints checking. After all, when we write a template we have the full expressive power of C++ available. Consider:

In addition, most people appreciate that sort() is type safe, that no casts are required to use it, and that they don't have to write a compare() function for standard types.

For a more detailed explanation, see my paper "Learning C++ as a New language", which you can download from my publications list.

The primary reason that sort() tends to outperform qsort() is that the comparison inlines better.

A function object is a more general concept than a function because a function object can have state that persist across several calls (like a static local variable) and can be initialized and examined from outside the object (unlike a static local variable). For example:

Function objects are extensively used to provide flexibility in the standard library.

Clearly, if your code has new operations, delete operations, and pointer arithmetic all over the place, you are going to mess up somewhere and get leaks, stray pointers, etc. This is true independently of how conscientious you are with your allocations: eventually the complexity of the code will overcome the time and effort you can afford. It follows that successful techniques rely on hiding allocation and deallocation inside more manageable types. Good examples are the standard containers. They manage memory for their elements better than you could without disproportionate effort. Consider writing this without the help of string and vector:

Note the absence of explicit memory management, macros, casts, overflow checks, explicit size limits, and pointers. By using a function object and a standard algorithm, I could have eliminated the pointer-like use of the iterator, but that seemed overkill for such a tiny program.

These techniques are not perfect and it is not always easy to use them systematically. However, they apply surprisingly widely and by reducing the number of explicit allocations and deallocations you make the remaining examples much easier to keep track of. As early as 1981, I pointed out that by reducing the number of objects that I had to keep track of explicitly from many tens of thousands to a few dozens, I had reduced the intellectual effort needed to get the program right from a Herculean task to something manageable, or even easy.

If your application area doesn't have libraries that make programming that minimizes explicit memory management easy, then the fastest way of getting your program complete and correct might be to first build such a library.

Templates and the standard libraries make this use of containers, resource handles, etc., much easier than it was even a few years ago. The use of exceptions makes it close to essential.

If you cannot handle allocation/deallocation implicitly as part of an object you need in your application anyway, you can use a resource handle to minimize the chance of a leak. Here is an example where I need to return an object allocated on the free store from a function. This is an opportunity to forget to delete that object. After all, we cannot tell just looking at pointer whether it needs to be deallocated and if so who is responsible for that. Using a resource handle, here the standard library auto_ptr, makes it clear where the responsibility lies:

Think about resources in general, rather than simply about memory.

If systematic application of these techniques is not possible in your environment (you have to use code from elsewhere, part of your program was written by Neanderthals, etc.), be sure to use a memory leak detector as part of your standard development procedure, or plug in a garbage collector.

Basically, someone resuming from an exception handler can never be sure that the code after the point of throw was written to deal with the execution just continuing as if nothing had happened. An exception handler cannot know how much context to "get right" before resuming. To get such code right, the writer of the throw and the writer of the catch need intimate knowledge of each others code and context. This creates a complicated mutual dependency that wherever it has been allowed has led to serious maintenance problems.

I seriously considered the possibility of allowing resumption when I designed the C++ exception handling mechanism and this issue was discussed in quite some detail during standardization. See the exception handling chapter of The Design and Evolution of C++.

If you want to check to see if you can fix a problem before throwing an exception, call a function that checks and then throws only if the problem cannot be dealt with locally. A new_handler is an example of this.

In C++, a better way of dealing with reallocation is to use a standard library container, such as vector, and let it grow naturally.

First of all there are things that just can't be done right without exceptions. Consider an error detected in a constructor; how do you report the error? You throw an exception. That's the basis of RAII (Resource Acquisition Is Initialization), which it the basis of some of the most effective modern C++ design techniques: A constructor's job is to establish the invariant for the class (create the environment in which the members function are to run) and that often requires the acquisition of resources, such as memory, locks, files, sockets, etc.

Imagine that we did not have exceptions, how would you deal with an error detected in a constructor? Remember that constructors are often invoked initialize/construct objects in variables:

So writing constructors can be tricky without exceptions, but what about plain old functions? We can either return an error code or set a non-local variable (e.g. errno). Setting a global variable doesn't work too well unless you test it immediately (or some other function might have re-set it). Don't even think of that technique if you might have multiple threads accessing the global variable. The trouble with return values are that choosing the error return value can require cleverness and can be impossible:

Common objections to the use of exceptions:

In C++, exceptions are used to signal errors that cannot be handled locally, such as the failure to acquire a resource in a constructor. For example:

A key technique is resource acquisiton is initialization (sometimes abbreviated to RAII), which uses classes with destructors to impose order on resource management. For example:

An alternative language design decision would have been to allow the unsafe conversion, but rely on dynamic checking. That would have required a run-time check for each access to v's members, and h() would have had to throw an exception upon encountering the last element of v.

If you really need a whole line (and not just a single word) you can do this:

Templates supports generic programming, template metaprogramming, etc. through a combination of features such as integer template arguments, specialization, and uniform treatment of built-in and user-defined types. The result is flexibility, generality, and performance unmatched by "generics". The STL is the prime example.

A less desirable result of the flexibility is late detection of errors and horrendously bad error messages. This is currently being addressed indirectly with constraints classes.

There is a caveat: Exceptions can't be used for some hard-real time projects. For example, see the JSF air vehicle C++ coding standards.

Also, have a look at the examples of resource management in Appendix E of The C++ Programming Language.

Auto_ptr is a very lightweight class. In particular, it is *not* a reference counted pointer. If you "copy" one auto_ptr into another, the assigned to auto_ptr holds the pointer and the assigned auto_ptr holds 0. For example:

This "move semantics" differs from the usual "copy semantics", and can be surprising. In particular, never use an auto_ptr as a member of a standard container. The standard containers require the usual copy semantics. For example:

An auto_ptr holds a pointer to an individual element, not a pointer to an array:

So should we use an auto_array to hold arrays? No. There is no auto_array. The reason is that there isn't a need for one. A better solution is to use a vector:

In C++11 use a Unique_ptr instead of auto_ptr.

In particular, throw is not simply an alternative way of returning a value from a function (similar to return). Doing so will be slow and will confuse most C++ programmers used to seing exceptions used only for error handling. Similarly, throw is not a good way of getting out of a loop.

Whenever you use malloc() you must consider initialization and convertion of the return pointer to a proper type. You will also have to consider if you got the number of bytes right for your use. There is no performance difference between malloc() and new when you take initialization into account.

malloc() reports memory exhaustion by returning 0. new reports allocation and initialization errors by throwing exceptions.

Objects created by new are destroyed by delete. Areas of memory allocated by malloc() are deallocated by free().

No, in the sense that you cannot allocate an object with malloc() and free it using delete. Nor can you allocate with new and delete with free() or use realloc() on an array allocated by new.

The C++ operators new and delete guarantee proper construction and destruction; where constructors or destructors need to be invoked, they are. The C-style functions malloc(), calloc(), free(), and realloc() doesn't ensure that. Furthermore, there is no guarantee that the mechanism used by new and delete to acquire and release raw memory is compatible with malloc() and free(). If mixing styles works on your system, you were simply "lucky" - for now.

If you feel the need for realloc() - and many do - then consider using a standard library vector. For example

See also the examples and discussion in "Learning Standard C++ as a New Language", which you can download from my publications list.

In C, you can implicitly convert a void* to a T*. This is unsafe. Consider:

One of the most common uses of this unsafe conversion in C is to assign the result of malloc() to a suitable pointer. For example:

If you want a constant that you can use in a constant expression, say as an array bound, you have two choices:

So why do these inconvenient restrictions exist? A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects. See D&E for an explanation of C++'s design tradeoffs.

You have more flexibility if the const isn't needed for use in a constant expression:

One reason is that the operand of delete need not be an lvalue. Consider:

If you consider zeroing out pointers important, consider using a destroy function:

Consider this yet-another reason to minimize explicit use of new and delete by relying on standard library containers, handles, etc.

Note that passing the pointer as a reference (to allow the pointer to be zero'd out) has the added benefit of preventing destroy() from being called for an rvalue:

Basically, you should only use "new" if you want an object to live beyond the lifetime of the scope you create it in. That done, you need to use "delete" to destroy it. For example:

Code that creates an object using new and then deletes it at the end of the same scope is ugly, error-prone, and inefficient. For example:

In C++, main() need not contain an explicit return statement. In that case, the value returned is 0, meaning successful execution. For example:

Sizeof cannot be overloaded because built-in operations, such as incrementing a pointer into an array implicitly depends on it. Consider:

In N::m neither N nor m are expressions with values; N and m are names known to the compiler and :: performs a (compile time) scope resolution rather than an expression evaluation. One could imagine allowing overloading of x::y where x is an object rather than a namespace or a class, but that would - contrary to first appearances - involve introducing new syntax (to allow expr::expr). It is not obvious what benefits such a complication would bring.

Operator . (dot) could in principle be overloaded using the same technique as used for ->. However, doing so can lead to questions about whether an operation is meant for the object overloading . or an object referred to by . For example:

This problem can be solved in several ways. At the time of standardization, it was not obvious which way would be best. For more details, see D&E.

It's not a language-technical problem. Even when I first considerd it in 1983, I knew how it could be implemented. However, my experience has been that when we go beyond the most trivial examples people seem to have subtlely different opinions of "the obvious" meaning of uses of an operator. A classical example is a**b**c. Assume that ** has been made to mean exponentiation. Now should a**b**c mean (a**b)**c or a**(b**c)? I thought the answer was obvious and my friends agreed - and then we found that we didn't agree on which resolution was the obvious one. My conjecture is that such problems would lead to subtle bugs.

The choice between ``int* p;'' and ``int *p;'' is not about right and wrong, but about style and emphasis. C emphasized expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.

A ``typical C programmer'' writes ``int *p;'' and explains it ``*p is what is the int'' emphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.

A ``typical C++ programmer'' writes ``int* p;'' and explains it ``p is a pointer to an int'' emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.

The critical confusion comes (only) when people try to declare several pointers with a single declaration:

Whenever something can be done in two ways, someone will be confused. Whenever something is a matter of taste, discussions can drag on forever. Stick to one pointer per declaration and always initialize variables and the source of confusion disappears. See The Design and Evolution of C++ for a longer discussion of the C declaration syntax.

I personally use what is often called "K&R" style. When you add conventions for constructs not found in C, that becomes what is sometimes called "Stroustrup" style. For example:

Design issues, such as the use of abstract classes for major interfaces, use of templates to present flexible type-safe abstractions, and proper use of exceptions to represent errors, are far more important than the choice of layout style.

So, I don't like naming a variable after its type; what do I like and recommend? Name a variable (function, type, whatever) based on what it is or does. Choose meaningful name; that is, choose names that will help people understand your program. Even you will have problems understanding what your program is supposed to do if you litter it with variables with easy-to-type names like x1, x2, s3, and p7. Abbreviations and acronyms can confuse people, so use them sparingly. Acronyms should be used sparingly. Consider, mtbf, TLA, myw, RTFM, and NBV. They are obvious, but wait a few months and even I will have forgotten at least one.

Short names, such as x and i, are meaningful when used conventionally; that is, x should be a local variable or a parameter and i should be a loop index.

Don't use overly long names; they are hard to type, make lines so long that they don't fit on a screen, and are hard to read quickly. These are probably ok:

Avoid names that are easy to mistype, misread, or confuse. For example

Often, your choice of naming conventions is limited by local style rules. Remember that a maintaining a consistent style is often more important than doing every little detail in the way you think best.

Why? When I invented "const" (initially named "readonly" and had a corresponding "writeonly"), I allowed it to go before or after the type because I could do so without ambiguity. Pre-standard C and C++ imposed few (if any) ordering rules on specifiers.

I don't remember any deep thoughts or involved discussions about the order at the time. A few of the early users - notably me - simply liked the look of

I may have been influenced by the fact that my earliest examples were written using "readonly" and

I remember discussing syntax alternatives with several people - incl. Dennis Ritchie - but I don't remember which languages I looked at then.

Note that in const pointers, "const" always comes after the "*". For example:

The "new-style casts" were introduced to give programmers a chance to state their intentions more clearly and for the compiler to catch more errors. For example:

A secondary reason for introducing the new-style cast was that C-style casts are very hard to spot in a program. For example, you can't conveniently search for casts using an ordinary editor or word processor. This near-invisibility of C-style casts is especially unfortunate because they are so potentially damaging. An ugly operation should have an ugly syntactic form. That observation was part of the reason for choosing the syntax for the new-style casts. A further reason was for the new-style casts to match the template notation, so that programmers can write their own casts, especially run-time checked casts.

Maybe, because static_cast is so ugly and so relatively hard to type, you're more likely to think twice before using one? That would be good, because casts really are mostly avoidable in modern C++.

Unfortunately, you cannot assume that other programmers consistently avoid what you consider "really stupid". For example, someone recently reported to me that they had encountered a macro containing a goto. I have seen that also and heard arguments that might - in a weak moment - appear to make sense. For example:

One of the most common subtle problems is that a function-style macro doesn't obey the rules of function argument passing. For example:

And yes, I do know that there are things known as macros that doesn't suffer the problems of C/C++ preprocessor macros. However, I have no ambitions for improving C++ macros. Instead, I recommend the use of facilities from the C++ language proper, such as inline functions, templates, constructors (for initialization), destructors (for cleanup), exceptions (for exiting contexts), etc.