Related
My question is pretty much an extension of this one: Is std::vector memory freed upon a clear?
Here people explained that the memory allocated for the elements of a std::vector is not released after calling clear(). But will this memory be free for the OS to allow other programs to use it or will it be available for my program to use it anywhere else?
If not (if the memory continues to be allocated only for this vector and I can't access it anymore) isn't it a memory leak like the ones we have with pointers? Then clear() when used alone like this would be totally unsafe right?
I would be happy if someone could clarify me in this one. Thanks.
Does clear() in std::vector generates a memory leak?
No.
But will this memory be free for the OS to allow other programs to use it or will it be available for my program to use it anywhere else?
OS can swap the memory to disk, to allow other programs to use the physical memory.
if the memory continues to be allocated only for this vector and I can't access it anymore
You can reuse the memory by adding new objects into the vector. Or release it by destroying the vector. The destructor absolutely guarantees to free the memory.
isn't it a memory leak like the ones we have with pointers?
No. A memory leak happens when the pointer to the memory is lost. But in this case the vector safely keeps track of the pointer, and frees it when it is destroyed.
Then clear() when used alone like this would be totally unsafe right?
clear isn't inherently unsafe, but the assumption that it will free the memory may be.
Here people explained that the memory allocated for the elements of a std::vector is not released after calling clear(). But will this memory be free for the OS to allow other programs to use it or will it be available for my program to use it anywhere else?
No, the memory will still be held by the std::vector instance, and will not be available for use by the rest of the program until the vector itself is destroyed, or shrink_to_fit is called1.
If not (if the memory continues to be allocated only for this vector and I can't access it anymore) isn't it a memory leak like the ones we have with pointers?
Not really. The memory is still released when the vector is destroyed.
Then clear() when used alone like this would be totally unsafe right?
As #user2079303 eloquently put it; clear isn't inherently unsafe, but the assumption that it will free memory may be.
1. Potentially. The call to shrink_to_fit is not guaranteed to free any memory.
It is not a leak. Generally speaking, a leak is when resources are allocated by your program and you lose all handles to them. An even stricter definition of a leak is when this resource allocation happens repeatedly over time.
A simple call to clear does not fulfill that definition, because you still have access to the std::vector object after the function call; the object does not simply disappear. You can still call shrink_to_fit on it, or swap it with an empty vector. And even that should not be necessary, because eventually, the std::vector will be destructed, and the destructor deallocates the occupied memory, or more correctly speaking, it deallocates the storage, because what happens on the OS or even hardware level is not in the scope of C++ language rules.
If the destructor is not run because the std::vector is never destroyed due to some buggy dynamic memory handling on your part, then the existence of the std::vector object itself already causes a potential leak. The problem is then not with the storage handled by the std::vector.
Note that clear still causes the std::vector's elements to be destroyed immediately. This has the important effect that their destructors are run. So when you have, for example, a std::vector<std::string>, and you call clear on it, then all the individual std::string destructors are run, and of course that causes storage to be deallocated immediately, provided that there was actually some dynamic content handled by the strings (i.e. Small-String Optimisation was not used). But it's not the storage handled by std::vector, but the storage handled by the std::strings'.
Functions like wcsdup, implicitly calls malloc to allocate memory for the destination buffer. I was wondering as the memory allocation is not very explicit, so does it seems logical to explicitly free the storage?
This is more like a design dilemma and the reasons for and against are as follows
Should be freed because
Not freeing it would cause Memory Leak.
It is well documented that wcsdup/_wcsdup calls malloc to allocate memory even when its called from a C++ Program.
Should not be freed because
Memory accumulated by wcsdup would eventually be freed when program exits. We always live with some memory leaks through out the program lifetime(Unless we are heavily calling wcsdup for large buffer size).
It can be confusing as free was not preceded by an explicit malloc.
As its not part of the standard but posix compliant, Microsoft implementation may not use malloc for allocating destination buffer.
What should be the approach?
From MSDN:
it is good practice always to release this memory by calling the free routine on the pointer returned
From the page you linked:
The returned pointer can be passed to free()
It seems fairly explicit: if you care about memory leaks, then you should free the memory by using free.
To be honest, I'm concerned about the cavalier attitude hinted at with this:
We always live with some memory leaks through out the program lifetime
There are very rarely good reasons to leak memory. Even if the code you write today is a one-off, and it's not a long-lived process, can you be sure that someone's not going to copy-and-paste it into some other program?
Yes, you should always free heap-allocated memory when you're done using it and know that it is safe to do so. The documentation you link to even states:
For functions that allocate memory as if by malloc(), the application
should release such memory when it is no longer required by a call to
free(). For wcsdup(), this is the return value.
If you are concerned about the free being potentially confusing, leave a comment explaining it. To be honest, though, that seems superfluous; it's pretty obvious when a pointer is explicitly freed that it's "owned" by the code freeing it, and anyone who does become confused can easily look up the wcsdup documentation.
Also, you should really never have memory leaks in your program. In practice some programs do have memory leaks, but that doesn't mean it's okay for them to exist. Also note that just because you have a block of memory allocated for the entire lifespan of the program, it is not leaked memory if you are still using it for that entire duration.
From your own link:
For functions that allocate memory as if by malloc(), the application should release such memory when it is no longer required by a call to free().
From MSDN:
The _strdup function calls malloc to allocate storage space for a copy of strSource and then copies strSource to the allocated space.
and strdup is deprecated as from MSVC 2005 and calling it calls _strdup so it is using malloc
How to check if memory to which pointer p points has been succesfully deallocated?
In few words: you can't.
Check out tools like Valgrind to help you debugging memory leaks issues.
Some other things you should consider:
Use smart pointers so that you don't have do think about memory management,
Set your pointers to 0 after you free them, so that a further delete has no effect,
Use standard classes (vector, ...) instead of rolling your own,
Finally, don't use pointers (actually you almost can)
Sorry, very short answer "You can't"
Use IBM rational purify tool to check correct deallocation of memory.
Define successfully! Define deallocated!
After deallocating memory (whether it is free or delete) you must not use that pointer again. All other assumptions are irrelevant.
After all, you call the C/C++ runtime to deallocate memory, but the C/C++ runtime also calls functions of the operating system to free the page. You could even have a custom memory allocator on top of the C/C++ runtime that e.g. uses caching to implement a faster memory allocation algorithm.
All of these layers may keep the deallocated memory for themselves (because of fragmentation or just because they like to keep it to themselves) or may tell the underlying layer to deallocate it. Anything can happen, just don't use that pointer anymore.
Some tools which are doing static code analysis can point some problems regarding the memory deallocation.
Use valgrind to check whether you have memory leaks
Avoid raw pointers - use smart pointers instead
Exception handling. I.e. try/catch blocks.
In C++, you can safely assume deallocation never fails. Destructors must not throw exceptions, and the actual memory reserved should never fail to be released, so given those two points, nothing can go wrong.
However, if you delete a pointer that has already been deleted, your program will probably crash. This isn't a problem with deallocation itself though - the original delete worked successfully. It's a problem with your program's memory management if it tries to delete a pointer twice, but that's rarely necessary with modern STL and smart pointers like std::vector, std::unique_ptr, etc...
In C++, when you make a new variable on the heap like this:
int* a = new int;
you can tell C++ to reclaim the memory by using delete like this:
delete a;
However, when your program closes, does it automatically free the memory that was allocated with new?
Yes, it is automatically reclaimed, but if you intend to write a huge program that makes use of the heap extensively and not call delete anywhere, you are bound to run out of heap memory quickly, which will crash your program.
Therefore, it is a must to carefully manage your memory and free dynamically allocated data with a matching delete for every new (or delete [] if using new []), as soon as you no longer require the said variable.
When the process is terminated the memory is reclaimed back by the OS. Of course this argument shouldn't in any case be used to not perform proper memory management by the program.
Don't let people tell you yes. C++ has no concept of an OS, so to say "yes the OS will clean it up" is no longer talking about C++ but about C++ running on some environment, which may not be yours.
That is, if you dynamically allocate something but never free it you've leaked. It can only end its lifetime once you call delete/delete[] on it. On some OS's (and almost all desktop OS's), memory will be reclaimed (so other programs may use it.) But memory is not the same as resource! The OS can free all the memory it wants, if you have some socket connection to close, some file to finish writing to, etc, the OS might not do it. It's important not to let resources leak. I've heard of some embedded platforms that won't even reclaim the memory you've not freed, resulting in a leak until the platform is reset.
Instead of dynamically allocating things raw (meaning you're the one that has to explicitly delete it), wrap them into automatically allocated (stack allocated) containers; not doing so is considered bad practice, and makes your code extremely messy.
So don't use new T[N], use std::vector<T> v(N);. The latter won't let a resource leak occur. Don't use new T;, use smart_ptr p(new T);. The smart pointer will track the object and delete it when it's know longer used. This is called Scope-bound Resource Management (SBRM, also known as the dumber name Resource-Acquisition is Initialization, or RAII.)
Note there is no single "smart_ptr". You have to pick which one is best. The current standard includes std::auto_ptr, but it's quite unwieldy. (It cannot be used in standard containers.) Your best bet is to use the smart pointers part of Boost, or TR1 if your compiler supports it. Then you get shared_ptr, arguably the most useful smart pointer, but there are many others.
If every pointer to dynamically allocated memory is in an object that will destruct (i.e., not another object that is dynamically allocated), and that object knows to free the memory, that pointer is guaranteed to be freed. This question shouldn't even be a problem, since you should never be in a position to leak.
No, when the program exits ("closes") the dynamically allocated memory is left as is
EDIT:
Reading the other answers, I should be more precise. The destructors of dynamically allocated objects will not run but the memory will be reclaimed anyway by any decent OS.
PS: The first line should read
int* a = new int;
No, it's your responsibility to free it. Also, a must be a pointer, so it should be:
int *a = new int;
delete a;
This excellent answer by Brian R. Bondy details why it's good practice to free the memory allocated by a.
It is important to explicitly call
delete because you may have some code
in the destructor that you want to
execute. Like maybe writing some data
to a log file. If you let the OS free
your memory for you, your code in your
destructor will not be executed.
Most operating systems will deallocate
the memory when your program ends. But
it is good practice to deallocate it
yourself and like I said above the OS
won't call your destructor.
As for calling delete in general, yes
you always want to call delete, or
else you will have a memory leak in
your program, which will lead to new
allocations failing.
When your process terminates, the OS does regain control of all resources the process was using, including memory. However, that, of course, will not cause C++'s destructors to be necessarily run, so it's not a panacea for not explicitly freeing said resources (though it won't be a problem for int or other types with noop dtors, of course;-).
First of all, using delete for anything allocated with new[] is undefined behaviour according to C++ standard.
In Visual C++ 7 such pairing can lead to one of the two consequences.
If the type new[]'ed has trivial constructor and destructor VC++ simply uses new instead of new[] and using delete for that block works fine - new just calls "allocate memory", delete just calls "free memory".
If the type new[]'ed has a non-trivial constructor or destructor the above trick can't be done - VC++7 has to invoke exactly the right number of destructors. So it prepends the array with a size_t storing the number of elements. Now the address returned by new[] points onto the first element, not onto the beginning of the block. So if delete is used it only calls the destructor for the first element and the calls "free memory" with the address different from the one returned by "allocate memory" and this leads to some error indicaton inside HeapFree() which I suspect refers to heap corruption.
Yet every here and there one can read false statements that using delete after new[] leads to a memory leak. I suspect that anything size of heap corruption is much more important than a fact that the destructor is called for the first element only and possibly the destructors not called didn't free heap-allocated sub-objects.
How could using delete after new[] possibly lead only to a memory leak on some C++ implementation?
Suppose I'm a C++ compiler, and I implement my memory management like this: I prepend every block of reserved memory with the size of the memory, in bytes. Something like this;
| size | data ... |
^
pointer returned by new and new[]
Note that, in terms of memory allocation, there is no difference between new and new[]: both just allocate a block of memory of a certain size.
Now how will delete[] know the size of the array, in order to call the right number of destructors? Simply divide the size of the memory block by sizeof(T), where T is the type of elements of the array.
Now suppose I implement delete as simply one call to the destructor, followed by the freeing of the size bytes, then the destructors of the subsequent elements will never be called. This results in leaking resources allocated by the subsequent elements. Yet, because I do free size bytes (not sizeof(T) bytes), no heap corruption occurs.
The fairy tale about mixing new[] and delete allegedly causing a memory leak is just that: a fairy tale. It has absolutely no footing in reality. I don't know where it came from, but by now it acquired a life of its own and survives like a virus, propagating by the word of mouth from one beginner to another.
The most likely rationale behind this "memory leak" nonsense is that from the innocently naive point of view the difference between delete and delete[] is that delete is used to destroy just one object, while delete[] destroys an array of objects ("many" objects). A naive conclusion that is usually derived from this is that the first element of the array will be destroyed by delete, while the rest will persist, thus creating the alleged "memory leak". Of course, any programmer with at least basic understanding of typical heap implementations would immediately understand that the most likely consequence of that is heap corruption, not a "memory leak".
Another popular explanation for the naive "memory leak" theory is that since the wrong number of destructors gets called, the secondary memory owned by the objects in the array does not get deallocated. This might be true, but it is obviously a very forced explanation, which bears little relevance in the face of much more serious problem with heap corruption.
In short, mixing different allocation functions is one of those error that lead to solid, unpredictable and very practical undefined behavior. Any attempts to impose some concrete limits on the manifestations of this undefined behavior are just waste of time and sure sign of the lack of basic understanding.
Needless to add, new/delete and new[]/delete[] are in fact two independent memory management mechanisms, which are independently customizable. Once they get customized (by replacing raw memory management functions) there's absolutely no way to even begin to predict what might happen if they get mixed.
It seems that your question is really "why heap corruption doesn't happen?". The answer to that one is "because the heap manager keeps track of allocated block sizes". Let's go back to C for a minute: if you want to allocate a single int in C you would do int* p = malloc(sizeof(int)), if you want to allocate array of size n you can either write int* p = malloc(n*sizeof(int)) or int* p = calloc(n, sizeof(int)). But in any case you'll free it by free(p), no matter how you allocated it. You never pass size to free(), free() just "knows" how much to free, because the size of a malloc()-ed block is saved somewhere "in front" of the block. Back to C++, new/delete and new[]/delete[] are usually implemented in terms of malloc (although they don't have to be, you shouldn't rely on that). This is why new[]/delete combination doesn't corrupt the heap - delete will free the right amount of memory, but, as explained by everyone before me, you can get leaks by not calling the right number of destructors.
That said, reasoning about undefined behavior in C++ is always pointless exercise. Why does it matter if new[]/delete combination happens to work, "only" leaks or causes heap corruption? You shouldn't code like that, period! And, in practice, I would avoid manual memory management whenever possible - STL & boost are there for a reason.
If the non-trivial destructor that are not called for all but the first element in the array are supposed to free some memory you get a memory leak as these objects are not cleaned up properly.
It will lead to a leak in ALL implementations of C++ in any case where the destructor frees memory, because the destructor never gets called.
In some cases it can cause much worse errors.
memory leak might happen if new() operator is overridden but new[] is not. same goes to the delete / delete[] operator
Apart from resulting in undefined behavior, the most straightforward cause of leaks lies in the implementation not calling the destructor for all but the first object in the array. This will obviously result in leaks if the objects have allocated resources.
This is the simplest possible class I could think of resulting in this behaviour:
struct A {
char* ch;
A(): ch( new char ){}
~A(){ delete ch; }
};
A* as = new A[10]; // ten times the A::ch pointer is allocated
delete as; // only one of the A::ch pointers is freed.
PS: note that constructors fail to get called in lots of other programming mistakes, too: non-virtual base class destructors, false reliance on smart pointers, ...
Late for an answer, but...
If your delete mechanism is simply to call the destructor and put the freed pointer, together with the size implied by sizeof, onto a free stack, then calling delete on a chunk of memory allocated with new[] will result memory being lost -- but not corruption.
More sophisticated malloc structures could corrupt on, or detect, this behaviour.
Why can't the answer be that it causes both?
Obviously memory is leaked whether heap corruption occurs or not.
Or rather, since I can re-implement new and delete..... can't it not cause anything at all. Technically I can cause new and delete to perform new[] and delete[].
HENCE: Undefined Behavior.
I was answering a question which was marked off as a duplicate, so i'll just copy it here in case it metters. It was said well before me the way memory allocation works, i`ll just explain the cause & effects.
Just a little thing right off google: http://en.cppreference.com/w/cpp/memory/new/operator_delete
Anyhow, delete is a function for a single object. It frees the instance from the pointer, and leaves;
delete[] is a function used in order to deallocate arrays. That means, it doesnt just free the pointer; It declares the whole memory block of that array as garbage.
That's all cool in practice, but you tell me your application works. You are probably wondering... why?
The solution is C++ does not fix memory leaks. If you`ll use delete without the parenthesises, it'll delete just the array as an object - a proccess which might cause a memory leak.
cool story, memory leak, why should i care?
Memory leak happens when allocated memory doesn't get deleted. That memory then requires unneccessary disk-space, which will make you lose useful memory for pretty much no reason. That's bad programming, and you should probably fix it in your systems.