views:

925

answers:

10

In order for an application to have no memory leaks, does the number of new in a C++ project match the number of delete?

+17  A: 

If you mean do you need the same number of instances of delete in your source code as you have instances of new, then no. You can have objects newed in multiple places, but all these objects deleted by the same line of code. In fact this is a common idiom.

Smart pointers, of varying types, generally take many different objects newed in many places in user code and delete them from a single place in library code.

Edit

Technically, every successfully memory allocation call needs to be matched with a dellocation call that takes the returned pointer from the original allocation call.

Most new expressions result in a call to an operator new that allocates the memory and the constructs an object in the newly allocated memory. Using a delete expression destroys the object and causes a call to an operator delete that should free the allocated memory.

There are new expressions that construct objects in pre-allocated memory (placement new). These should not be matched by a delete expression, but the pre-allocated memory may need to be deallocated in a way that corresponds to the original allocation.

Charles Bailey
A: 

Well, it can if you have exactly no news and no deletes, or if you have other classes, eg the stl, to manage memory for you.

You need to match the number of calls to new with the number of calls to delete.

More often than not it gets more complicated that that.

quamrana
You don't necessarily need the same amount of news and deletes.
Partial
@Partial: Can you explain that?
quamrana
a[0] = new int; a[1] = new int; for (int i=0;i<2;i++) delete a[i];
Pavel Shved
@Pavel: So you have two calls to new and two calls to delete.
quamrana
Sorry about that I misread something, somewhere.
Partial
+1 to your comment and changed what I add written in my answer.
Partial
+7  A: 

Yes. Every new must be matched by a delete.

However, the delete is often hidden from you - for example:

{
  std::auto_ptr p( new Foo );
}

Here there is a new, but the delete (which occurs automatically at the end of the block) is hidden in the std::auto_ptr implementation.

anon
The number of (non-placement) calls to `new` must match the number of calls to `delete`, but I'm not sure that's what the question asker meant by the number of `new` in a C++ project.
Charles Bailey
Well, don't ask me - ask the questioner!
anon
OK, Point taken!
Charles Bailey
+2  A: 

There are sophisticated tools like Rational's Purify to test for memory leaks n C++ programs. Unfortunately it is in general a highly non-trivial problem to verify the code itself is free of memory leaks before runtime. Therefore, keep it simple, follow best practices and test as much as possible in runtime.

Alex
A: 

Not exactly. Any object allocated using the new operator must be deallocated using the delete operator. Its fine to have an number of operators (new or delete) in different branches.

Personally I use boost's shared_ptr when writing c++ code.

Steve
A: 

To avoid memory leaks, your application should free all the memory it's not using anymore unless it allocates it during its termination. There's no notion of memory leak in a program without an event loop (because, well, their lifetime is termination from the very beginning :-) ).

But that's for grown up guys. For you, yes, every new should have a corresponding delete (this means, during the execution of a program, not in your source code!) Produce a good code, don't shoot yourself in the foot!

Pavel Shved
I disagree with the idea that you shouldn't worry about deallocating memory during termination. Problem (1): Sometimes important operations happen inside destructors that have consequences outside the currently running executable (file removal, etc.). Releasing memory is not the only thing that happens during a delete. Problem (2): Having a constant memory leak inside your app makes it harder to find real memory leaks that you care about, as you can "get used to" all the memory leak warnings, and then ignore new ones.
David Coufal
It is absolutely wrong to say that a program without an event loop has no notion of memory leak. And it is wrong to pretend that memory leaks are ok, just because the memory is released when the process terminates. Consider a program that does a long iterative calculation on a huge data set, like processing a video. If it leaks memory on every video frame, it is likely to run out of memory and crash long before it is done. All without an event loop.
Dima
(1) You can run out of memory without memory leaks. (2) "Destruction is finalization" has nothing to do with memory leaking, because, if you use this practice, you already are involved in new/delete balancing even if it ad nothing to do with leaks. (3) Having a constant memory leak is not a good habit, but there _are_ situations when you have mre important stuff to do than freeing memory--for example, when app's crashing. Okay, that's not a discussion board, just keep voting down If you don't like what I said.
Pavel Shved
@David Coufal: It's not always that simple. I once managed to write a program that flushed its last output file after 2 hours, then spent 4(!) hours deleting memory. Forcefully terminating my program after the flush made it 67% faster. Root cause was that I spent most of the two hours sorting records, and deallocation was randomly touching memory as a result. Cache efficiency was basically 0%.
MSalters
A: 

You need to match a call to new with a call to delete. Since C++ is an object oriented programming language, consider using a class to create (in the constructor) and to delete (in the destructor) the variables declared or used in the class. In fact, that would be taking the advantage of the Resource Acquisition Is Initialization or RAII (for short) idiom. If you don't feel like programming this yourself you can always use memory from the STL.

One important note: if you allocate a variable with a new and your code can throw an exception, you can leak memory if that exception is not caught and the variable deleted accordingly.

Partial
+14  A: 

If you meant "in the source code", then No.

See this code :

int main()
{
    char* buffer = 0; 


    for( int i = 0; i < 42; ++i )
    {
        buffer = new char[1024];
    }

    delete [] buffer; 

    return 0;
}

1 new, 1 delete, ((42 - 1) * 1024) bytes of memory leaked.

If you meant "new and delete call at runtime" then yes. Each memory aquired with new have to be released with delete:

int main()
{
    std::vector<char*> bufferList; // or nullptr or NULL whatever


    for( int i = 0; i < 42; ++i )
    {
        bufferList.push_back( new char[1024] );
    }

    for( int i = 0; i < bufferList.size(); ++i )
    {
        delete [] bufferList[i]; 
    }

    return 0;
}

Now at execution we got a delete executed for each new executed <=> no leak.

Klaim
@Klaim: I voted you up for your first section of code as it clearly showed the difference between the number of call sites and the number of runtime calls. Can you fix up your newly added code to delete something that exists? Perhaps you could iterate over the vector?
quamrana
Oups! Fixed! :)
Klaim
Excellent Example, Klaim
mahesh
A: 

If you are up to finding a preliminary way to detect memory leaks, counting new/deletes won't help at all. However, if you use MS VC, you can use CRT to perform very basic but useful leaks detection for you:

_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT);
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

This will cause CRT to call _CrtDumpMemoryLeaks right before CRT is unloaded. If there is any, it will dump them to the console:

Detected memory leaks!
Dumping objects ->
{342} normal block at 0x05A28FD8, 4 bytes long.
 Data: <    > 00 00 00 00 
Object dump complete.

There is also a technique to find the exact place of leak using the number of a block ({342}), but sometimes it is just enough to know whether there are any leaks.

It does not replace the need in proper memory leaks detection tools, but may limit the needs of them.

I always use this technique in unit tests. Allows me to detect very dumb memory leaks very early.

blinnov.com
+1  A: 

Are you asking about run time call count (e.g. counted using a instrumenting profiler)? Having exactly the same number of calls to the new (excluding placement new) and delete operators is neither a necessary nor sufficient condition of leak-free code:

  • Deleting NULL is harmless, so many leak-free programs call delete more times than new.
  • A program that calls delete as many times as new but sometimes deletes NULL has a leak. So do some programs that call delete more times than new but sometimes delete NULL.
  • A program that calls new more often than delete has a leak.

To validate that there are no leaks, you must verify that each address returned from new is passed to delete, not just verify that the call count matches. And even that's oversimplifying, since addresses are reused for multiple allocations.

Also, programs that don't leak memory that they have allocated may still leak other resources (such as OS file handles).

bk1e