In order for an application to have no memory leaks, does the number of new in a C++ project match the number of delete?
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 new
ed in multiple places, but all these objects delete
d by the same line of code. In fact this is a common idiom.
Smart pointers, of varying types, generally take many different objects new
ed 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.
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.
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.
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.
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.
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!
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.
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.
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.
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 calldelete
more times thannew
. - A program that calls
delete
as many times asnew
but sometimes deletesNULL
has a leak. So do some programs that calldelete
more times thannew
but sometimes deleteNULL
. - A program that calls
new
more often thandelete
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).