0

I came across having the need to create 2 or 3-level nested vectors but I had this issue of memory not clearing correctly. So I made this simple test:

void test(){
vector<vector<double>> myContainer;

vector<double> vec = {1};
for (int i=0; i<20000000; ++i)
{
    myContainer.push_back(vec);
}
FreeAll(myContainer);
}    

where FreeAll() is a template function defined as follows:

template <typename T>
void FreeAll( T & t ) {
T tmp;
t.swap(tmp);
}

Now, invoking function test() in main(), we will find out that a lot of left over memory is still there even after leaving the test function's scope and that memory is not cleared up until the main terminates.

Could be the reason for this that I create too much vectors? also there is no any kind of memory leak here as all the storage is automatic.

Eslam
  • 123
  • 2
  • 10
  • 1
    How are you determining that there is a lot of left over memory? It's not always the case that freeing C++ heap space will result in that memory being returned to the OS, if that is what you are checking. – clstrfsck Mar 26 '17 at 08:35
  • Simple, after leaving the scope of test function there's like more than 1 GBs still in RAM showing in system monitor, you might be correct, the memory hasn't returned to the OS but the question remains Is this memory now available for allocation by other containers? – Eslam Mar 26 '17 at 09:18
  • There are many different memory views and many different system monitors. We do not know what tools you are using or even the OS. – user4581301 Mar 26 '17 at 09:19
  • FYI, before running my RAM is at 2.8 GB after allocation memory is at 3.9 GB after Calling FreeAll() it's at 3.5 GB and after main terminates it's at 2.8 GB – Eslam Mar 26 '17 at 09:20
  • Are you looking at virtual memory, working set, what? – user4581301 Mar 26 '17 at 09:23
  • Ubuntu 14.04 LTS. and I'm using its default system monitor. and also turning the vector> to vector and storing the same number of doubles in it and then call FreeAll(), it operates correctly and the memory is back at 2.8 even before leaving the test function's scope. – Eslam Mar 26 '17 at 09:23
  • Linux hordes memory in case you need it again. The OS can take it back if someone else needs it. A better measure of whether you are leaking would be Valgrind. – user4581301 Mar 26 '17 at 09:28
  • There is no memory leak I checked with Valgrind and it makes sense as there's no any dynamic storage. before and after the program there's is no change in memory. I've no memory leaks. but what worries me is when is it that my memory is back again. I want the memory to be back right after I call FreeAll() and not after the program terminates. – Eslam Mar 26 '17 at 09:35
  • Nothing in your code should leak and valgrind saw nothing. I wouldn't worry about it, but as an experiment, what if you run your program and halt it after FreeAll four times? do you see four times as much RAM? – user4581301 Mar 26 '17 at 09:41
  • I tested out your experiment. and it confirms that there is not memory leak as the memory is cleared once I closed the program before call FreeAll(). otherwise the memory wouldn't have been cleared. – Eslam Mar 26 '17 at 09:53
  • A Final experiment would be to call test() 4 times. and check if the last 3 calls will allocate more or reuses the previous memory. and it turns out the no extra memory were allocated the memory is indeed reusable. – Eslam Mar 26 '17 at 09:57
  • Nowadays, clear+shrink_to_fit are simpler than the swap idiom. – Marc Glisse Mar 26 '17 at 10:15
  • shrink_to_fit is a non-binding call and is not guaranteed to operate correctly as it might clear more memory that expected. – Eslam Mar 26 '17 at 10:34
  • "clear more memory" uh, did you mean "less" instead? People keep repeating this non-binding request stuff, but honestly, if it isn't going to release memory, the function is useless (and it was added to the standard, so hopefully it isn't). All implementations do release memory in this case, and if one didn't, you would have good reasons to complain to your vendor. If you don't trust your vendor to implement the standard sensibly, there are way worse things they can do behind your back... – Marc Glisse Mar 26 '17 at 16:31
  • when I read about shrink_to_fit, it was all about the underlying blocks of allocation and deallocation. The mentioned example is just a test and it uses only double as its basic data type (8 bytes). The real problem kicks in when you create an object of your class and use it instead of the double. what if the object needs 11 bytes? how would shrink_to_fit manage such case? would it deallocate more or less memory than necessary? if it's more then it's dangerous! . The term "more" here refers to the fact that you cleared stuff that you shouldn't have cleared in the first place. – Eslam Mar 27 '17 at 07:18
  • You seem to misunderstand what shrink_to_fit does, the danger you are talking about doesn't exist (or you explanation of it is very unclear). – Marc Glisse Mar 27 '17 at 07:34
  • So Is it safe to always call shrink_to_fit right after clearing the vector? – Eslam Mar 27 '17 at 08:25

1 Answers1

0

In this very context, there is no any sort of memory leaks and memory observations occurred from Ubuntu's default system monitor.

So calling test() 4 times in main() and check if the last 3 calls would allocate more memory or reuse it from the previous allocation and it turns out that no more memory would be allocated and the memory is indeed reusable and it will be only freed once the program terminates. On the contrary, creating a vector of double and pushing the same number of doubles and call FreeAll(), it will actually free the memory instantly and it's returned to the OS.

Eslam
  • 123
  • 2
  • 10