Does C++ delete operator really free memory?
Posted on Wed 20 September 2017 in IT, programming
Well, I have been wondering about this for quite a while now, and I have tried to run some tests to better understand what's going on under the hood. The standard answer is that after you call delete you should not expect anything good from accessing that memory spot. However, this did not seem enough to me. What is it really happening when calling
delete(ptr)? Even though there no standard behavior, what could happen, anyway? Here's what I've found. I'm using g++ on Ubuntu 16.04, so this may play a role in the results.
What I first expected when using the delete operator was that the freed memory would be handed back to the system for usage in other processes. Let me say this does not happen under any of the circumstances I have tried.
Memory released with
delete still seem to be allocated to the program it first allocated it with new. I have tried, and there is no memory usage decrease after calling delete. I had a software which allocated around 30MB of lists through new calls, and then released them with subsequent delete calls. What happened is that, looking at the System monitor while the program was running, even a long sleep after the delete calls, memory consumption my the program was the same. No decrease! This means that delete does not release memory to the system.
In fact, it looks like memory allocated by a program is his forever! However, the point is that, if deallocated, memory can be used again by the same program without having to allocate any more. I tried to allocate 15MB, freeing them, and then allocating another 15MB of data after, and the program never used 30MB. System monitor always showed it around 15MB. What I did, in respect to the previous test, was just to change the order in which things happened: half allocation, half deallocation, other half of allocation.
So, apparently memory used by a program can increase, but never shrink. I thought that maybe memory would really be released for other processes in critical situations, such as when there is no more memory available. After all, what sense would it make to let a program keep its own memory forever, when other processes are asking for it? So I allocated the 30MB again, and while deallocating them I run a memtester with as much physical memory I could. I expected to see my software hand out its memory to memtester. But guess it, it did not happen!
I've made up a short screencast that shows the thing in action:
To be 100% honest, there was a situation in which something happened. When I tried memtester with more than the available physical memory in the middle of the deallocation process of my program, the memory used by my program dropped to around 3MB. The memtester process was killed automatically though, and what happened was even more surprising! The memory usage of my program increased with each delete call! It was just as if Ubuntu was restoring all its memory back after the memtester incident.
A situation in which freeing memory worked
So, I've said that free calls don't seem to release memory, and I've backed that claim with details and a gif screencast of my tests. However, there was a situation in which
free did actually free memory!
This happened in my Hilbert Image to Sound script. That code loads an image into memory, does some processing to it creating a new matrix of equal size and then a couple arrays of quite some length. I tried freeing memory and sleeping for a while after each free call, and indeed the memory usage of the app did decrease!
I can't provide an explanation for why this happened in this script but not in the other one, but if any of you know, please comment!