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'.
Related
creating a vector:
std::vector<int> pqrs;
delete in proper way to free up all memory (prevent memory leaks and other memory related issues) inside the function:
pqrs.clear();
std::vector<int>().swap(pqrs);
My question is: both clear and swap required (say for calling destructor)? or swap is sufficient for all purpose.
In case of std::vector<int> you don't need to do either clear() nor swap to free memory, because elements of std::vector<int> here (ints) are automtically allocated and freed by the std::vector<int> methods anddestructor. Data will be freed at the end of scope (function or program).
Hence,answer to your question would be, You don't need to call clear or swap.
Since vector<int> object in above question is a variable with automatic storage - so it will be automatically destroyed when it goes out of scope. And when a container object goes out of scope, it's destructor is called which in-turn frees up space used for storage of contained elements and during this step destructor for all contained elements also gets invoked (in case of user-defined types). So, if we have just plan int elements, no need to do anything extra. But we would have memory leak if contained type if T* where T is some user-defined type because in that case destructor wouldn't be called explicitly for pointed-to objects.
Your phrase about memory leaks makes the whole meaning of the question unclear. When the vector goes out of scope, the memory is released. There should be no memory leak.
In major projects, it is fairly common to need a vector to release its allocation at a certain point before it goes out of scope. Failure to do so is not a memory leak but may be a problem. For that purpose, .clear() is useless. The swap approach you suggested (without the .clear) works. I don't know a way to do it without swap.
I am here stuck with a question in my C++ book with the following:
"What does the use of new require you to also call delete?"
Maybe you have an answer for that?
Because that is the way C++ is designed & that is the intended behavior.
The intention was to provide a memory allocation which you demand and own till you reliquish it explicitly.
new gives you a dynamic memory allocation(on heap) which will continue to exist and you own it untill you explicitly deallocate it by calling delete.
Failing to call a delete on a newed buffer will lead to Undefined Behaviors usually in the form of. 1 memory leaks.
1 This was discussed here.
when you do a new, OS allocates the memory to the pointer you are assigning it. After your usage is completed you may not require it anymore. But the memory is still marked as "being used" by OS.
Now, when the pointer is declared in a scope of a function or any other block (of {}), it will be deleted (only pointer will be removed) when the execution of the block is over. In such cases the memory that was allocated using new is remained marked "being used" by OS and is not allocated to any other pointer that calls new or to a variable. This causes an orphan block of memory in RAM, that will never be used because its pointer was removed from memory but it will occupy a memory block.
This is called a memory leak. A few of such blocks may make your application unstable as well.
You use delete to free such memory blocks and relieve the OS so that it can be used well for other requests
There is no Garbage Collector in C++, and therefore you are responsible for deallocating the allocated memory. Anyway, the operating system "knows" what memory your program allocated. So when your program exits, the operating system is again responsible for the memory. But if you have a long running C++ program and never call delete noone will help you to get rid of your garbage.
Calling new has allocated memory for the object and it has also arranged for the constructor of that object to be executed.
You could free the memory by calling free(), but you should actually use delete to free memory allocated by new, since this will also cause the objects destructor to be executed.
In some classes I have an static std::map with pointers inside. My question is if I need to delete at the end of the program or this memory is automatically freed. My concern is if the pointers stored inside are correctly deleted through our destructors when std::map is deleted.
Thanks.
If the map contains pointers that were allocated with new (or new[], or malloc), then each pointer needs a corresponding delete (or delete[], or free).
The map's destructor wont know what to do with a bald pointer. Consider using a smart pointer that has appropriate move semantics like a boost smart pointer or if you've got a very new compiler, one of the C++0x smart pointers. However, do not use the current standard's std::auto_ptr, inside of STL containers. See this thread for why.
Edit:
As Billy ONeal pointed out, boost::ptr_map is also designed exactly for this purpose.
If I understand the situation correctly, you don't delete the map itself. But you probably need to delete the objects the map is pointing to. It would probably be a really good idea to use a smart pointer such as Boost shared_ptr in your map instead of native pointers. Then the objects would be cleaned up automatically.
Edit:
Using Boost ptr_map might be an even better idea.
The memory is "automatically freed", in the sense that the entire process memory is freed, but the destructors of the objects pointed to will not be called. This can cause a resource leak, if you use RAII.
std::map never calls delete on it's members. Assuming you're working with a relatively recent operating system, the OS will reclaim the memory occupied by the members on process termination, but the destructors will not run.
If you have a map of pointers, then the answer is 'no', your destructors will not be called, but 'yes', the memory will be freed at the end of process execution. All memory allocated by a process is always freed by the Operating System when a process exits (even if it crashes), but destructors might not be called.
A memory "leak" is where memory is unintentionally not deleted over a period of time, and ends up reducing as the process continues. If it is a type of process that runs for a very long period of time, eg a server that is rarely restarted, this can be a major problem.
Memory leak detectors will pick up on any memory that is allocated and not deleted by a programming call, so valgrind, etc. will report this as a leak.
It is as well to check your code with programs like valgrind, and therefore the less that "gets in the way", the easier it will be to spot real leaks. Therefore my advice is not do just let the system clean up the memory, or singletons, etc, for you when you have allocated a pointer with new (or malloc or new[]).
You can have a "clean-up" routine to do this. Just have an object in the scope of your map that has a deleter (as it will be deleted when it exits) that will clean up the pointers in the map. As you need your object to be deleted first it should be declared later than the map.
Like in any case of storage class which stores pointers: you are responsible to deallocate memory they point to. Storage class is responsible only to clean its own resources. Relying on reclaiming memory by OS at the process termination is a bad practice.
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;-).