简体   繁体   中英

CArray not de-allocating memory

I have a very simple problem and I seem to be stumped at whatever is happening. Look at the following code:

CArray<double, double&> arr;
arr.SetSize(50000);

for(int i =0; i< 50000; i++)
{
    arr[i] = (i+2)*3.14f;
}

arr.RemoveAll();

I would assume that after RemoveAll() , the memory would be freed but it seems like it is not happening. To check memory footprint, open Taskmanager and watch your exe's Memory. It increases on arr.SetSize() call but it never decreases even when this arr goes out of scope. Can somebody shed some light on nthis?

First thing:

Task Manager != Memory Profiler

The operating system (or more specifically the C runtime system) would certainly cache some of the memory you allocate.

Note that the operating system usually isn't dumb - if it's memory that's not being used by the application and the OS needs more memory to satisfy some other program's memory needs, it will allocate accordingly. But if that's not the case (it isn't most of the time), then keeping it for the application to reuse when is a winning strategy.

Because of these sort of optimizations, you really can't use Task Manager to get an accurate view of an application's memory usage.

Second thing:

Like all non-stupid dynamic array classes, CArray doesn't release the memory backing the array even when you remove all the elements in case you need to use the memory buffer again. It would be an awful waste of processor cycles to delete the underlying memory buffer only to find that you need to waste even more processor cycles to reallocate another buffer to handle your next CArray::Append() call that might come right after a CArray::RemoveAll() .

Should you really want to get rid of that extra space, use CArray::FreeExtra() . Note that the function may involve allocating a new buffer and copying the elements over to the new one, then deleting the old buffer.

As the others stated, RemoveAll does not release the memory that CArray allocated, you need to call CArray::FreeExtra.

You said that the memory does not go down after CArray's destructor. CArray::SetSize allocates memory from the heap, CArray's destructor frees it. But that does not mean that the heap memory is given back to the operating system.

When you are using MFC I suggest that from time to time you start your program in the debugger. MFC debug applications print out their memory leaks (based on new) during MFC cleanup.

You need to call FreeExtra after your RemoveAll to get the memory back. I'm guessing this is an effort to avoid heap fragmentation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM