CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Guest

    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


  2. #2
    Join Date
    May 1999
    Location
    UK
    Posts
    59

    Re: CStringArray behavior - interesting...

    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

  3. #3
    Join Date
    Jun 1999
    Posts
    9

    Re: CStringArray behavior - interesting...

    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.




  4. #4
    Guest

    Re: CStringArray behavior - interesting...

    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


  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CStringArray behavior - interesting...

    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


  6. #6
    Join Date
    Jan 2003
    Location
    India
    Posts
    52

    Re: CStringArray behavior - interesting...

    I am facing the similar problem has anyone got any solution to this?

  7. #7
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    Re: CStringArray behavior - interesting...

    Quote Originally Posted by Mab
    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.

  8. #8
    Join Date
    Jan 2002
    Location
    Houston, TX
    Posts
    1,421

    Re: CStringArray behavior - interesting...

    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.
    Be sure to rate those who help!
    -------------------------------------------------------------
    Karl - WK5M
    PP-ASEL-IA (N43CS)
    PGP Key: 0xDB02E193
    PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured