PRB: CString::ReleaseBuffer() Does Not Release Extra Memory

Last reviewed: July 10, 1997
Article ID: Q114201
1.00 1.50 1.51 1.52 | 1.00 2.00 2.10 4.00
WINDOWS             | WINDOWS NT
kbprg kbprb

The information in this article applies to:

  • The Microsoft Foundation Classes (MFC) included with:

        - Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, and 1.52
        - Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 2.1, and 4.0
    

SYMPTOMS

When CString::ReleaseBuffer is called and the length of the string is less than the allocated buffer length, the extra bytes are not released. This just means that your program might end up maintaining more memory than absolutely necessary. This will not cause a memory leak. All of the memory will be freed when the CString object is destroyed.

CAUSE

The behavior of CString::ReleaseBuffer described above is by design.

RESOLUTION

Visual C++ 2.0 and later include CString::FreeExtra to release any unused memory.

In earlier versions, one way to make the string's buffer length equal to the string's data length is to write a function which will free the extra memory. The two functions in the sample code section demonstrate two different methods of writing this function; either as a member function of a derived CString class or as a separate function which accepts a CString parameter type. Note that if the member function approach is taken, then the derived class will need to override the constructors provided by the CString class in order to have access to them.

MORE INFORMATION

By not freeing the extra bytes of memory in ReleaseBuffer, CString provides a simple method of growing without having to allocate more memory while keeping memory fragmentation to a minimum. For example, calling ReleaseBuffer(20) when the string's allocated buffer length is 200 bytes will leave an extra 180 bytes free. This way, the only time that a CString object will need to allocate more memory is when the data length exceeds the allocated buffer length.

Sample Code

1) Member function method

class CMyString : public CString {

  public:
    CMyString(const char* psz = NULL) : CString(psz) {}
    void FreeExMem();
};

void CMyString::FreeExMem()
{
  ASSERT(m_nDataLength<=m_nAllocLength);
  if(!IsEmpty())
  {
    char *tp = new char[m_nDataLength+1];
    memcpy(tp,m_pchData,m_nDataLength+1);
    ASSERT(m_pchData[m_nDataLength]=='\0');
    delete m_pchData;
    m_pchData = tp;
    m_nAllocLength = m_nDataLength;
  }
  ASSERT(m_pchData!=NULL);
}

2) Separate Function Method

void FreeExMem(CString &s)
{
  if(!s.IsEmpty())
  {
    char *p = s.GetBuffer(1);
    char *tp = new char[s.GetLength()+1];
    memcpy(tp,p,s.GetLength()+1);
    s.ReleaseBuffer();
    s.Empty();
    s = tp;
    delete tp;
  }
}


Additional reference words: 1.00 1.50 2.00 2.10 2.50 2.51 2.52 3.00 3.10
4.00
KBCategory: kbprg kbprb
KBSubcategory: MfcMisc
Keywords : MfcMisc kbprb kbprg
Technology : kbMfc
Version : 1.00 1.50 1.51 1.52 | 1.00 2.00
Platform : NT WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 10, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.