Click to See Complete Forum and Search --> : CStringArray behavior - interesting...
VC++ 6.0 SP2, NT4 SP5
While testing CStringArray speed and memory usage, I noticed that in DEBUG build, RemoveAll() would free up all of the memory it allocated (for 1,000,000 strings this was about 80MB), but in RELEASE build it released only about 4MB (this would be just the CString array used by CStringArray internally), thus leaving about 75MB still allocated. I am assuming this has nothing to do with CStringArray, it is most likely something to do with CString, but I don't see why in a release build it would not release all the allocated memory.
Can anyone explain this?
Thanks,
Stan
Marqy
May 6th, 1999, 04:11 AM
How did you allocate the CStringArray and it's objects? If you used new, then in a _DEBUG build you're actually calling DEBUG_NEW, which allocates (a lot) of extra memory to kepp track of your memory allocation. That way, if your program leaks or generates protection faults DevStudio can tell you the object that leaked/gpf'ed. In a _RELEASE build, none of this takes place so the allocation size is smaller.
MJA
Mab
May 6th, 1999, 09:08 AM
CStringArray is derived from COBArray: RemoveAll does not delete the Objects just the pointers. The following is from the CObArray documentation and I see no additions to the CStringArray documentation.
CObArray::RemoveAll
void RemoveAll( );
Remarks
Removes all the pointers from this array but does not actually delete the CObject objects. If the array is already empty, the function still works.
The RemoveAll function frees all memory used for pointer storage.
I just used:
CStringArray sa;
sa.SetSize(0, 50000); // Grow in blocks of 50,000
Sleep(5000); // Wait so I can see the memory usage in Task Manager
for(int i=0;i<1000000;i++)
sa.Add("asdf");
Sleep(5000); // Wait so I can see the memory usage in Task Manager
sa.RemoveAll();
Sleep(5000); // Wait so I can see the memory usage in Task Manager
At the end, the memory usage in Debug build is down to around 1MB (all memory has been released), but in Release build the memory usage only goes down about 4MB, so it stays at 75MB....
Any ideas?
Stan
Paul McKenzie
May 6th, 1999, 04:45 PM
This is all speculation, but I'll hazard a guess at what you are witnessing:
Possibly release build uses a different heap management than debug. Note the words *heap management*.
Depending on the heap manager, if you orignally allocated 75Meg, the C++ heap manager may just move a couple of pointers around when you "free" the 75 meg. You're not actually freeing, you are just letting the heap manager know that "your CStringArray is no longer used, and any further allocations can be salvaged from the 75 meg".
The possible reason for this is that Windows takes a longgggg time to physically free up all of that memory, so the C++ heap manager outsmarts the slow Windows system by managing the memory it already has allocated.
Unless your program allocates all memory using GlobalAlloc and frees with GlobalFree, looking at the Task Manager is not a sound way of determining how much memory your C++ program has available.
Regards,
Paul McKenzie
amolpg
September 18th, 2006, 10:26 PM
I am facing the similar problem has anyone got any solution to this?
GCDEF
September 19th, 2006, 07:23 AM
CStringArray is derived from COBArray: RemoveAll does not delete the Objects just the pointers. The following is from the CObArray documentation and I see no additions to the CStringArray documentation.
CObArray::RemoveAll
void RemoveAll( );
Remarks
Removes all the pointers from this array but does not actually delete the CObject objects. If the array is already empty, the function still works.
The RemoveAll function frees all memory used for pointer storage.
That's not the problem here as CStringArray strores CStrings and not pointers to objects. RemoveAll in a CStringArray deletes the CStrings as well.
krmed
September 19th, 2006, 07:24 AM
Once again this may not be a memory leak as you suspect.
Since you state that you are looking at memory usage in the Task Manager, the memory usage you see may actually be the working set. When you debug, Visual Studio may well be trimming this value down, but when you run the release version, that may not be happening.
After you believe you have released your memory, (with your app still running in release) minimize the window and then look at the usage in the Task Manager - it will drop because when you minimize, it releases the memory.
You can get more information about this by searching for "Process Working Set".
(Of course the previous posts are also possibilities!)
Hope that helps.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.