Adam Stepniak
Adam Stepniak

Reputation: 877

Why should I use GetBuffer member of CString instead of SetAt?

I'm currently studying MFC library and I wonder why should I use GetBuffer member which returns pointer to CString object buffer over other member functions which allow to read and change characters in that object? For example why should I do (code changes first character of CString object):

CString aString(_T("String")); //new CString object
LPTSTR p = aString.GetBuffer(); //create new pointer to aString buffer
_tcsncpy(p, LPCTSTR(_T("a")), 1); //set first character to 'a'
aString.ReleaseBuffer(); //free allocated memory

Instead of:

CString aStr(_T("String")); //new CString object
aStr.SetAt(0, _T('a')); //set character at 0 position to 'a'

I suppose there is a more appropriate application to use GetBuffer() member, but I can't figure out what it can be... This function requires ReleaseBuffer() to free memory, and I may cause memory leaks when ReleaseBuffer() is not called. Is there any advantage of using it?

Upvotes: 2

Views: 1878

Answers (2)

acraig5075
acraig5075

Reputation: 10756

Don't use GetBuffer unless you have no alternative. Precisely because of (1) the reason you already know, that it must be followed with ReleaseBuffer which you may forget to do, leading to a resource leak. And (2) you might inadvertently make changes to the underlying data rendering it inconsistent in some way. More often than not the functions GetString, SetString, GetAt and SetAt will do what you need and have no disadvantages. Prefer them.

Upvotes: 3

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

In above example it is preferable to use the SetAt method.

In some cases you need GetBuffer to directly access the buffer, mainly when used with WinAPI functions. For example, to use ::GetWindowText with WinAPI code you need to allocate a buffer as follows:

int len = ::GetWindowTextLength(m_hWnd) + 1;
char *buf = new char[len];
::GetWindowText(m_hWnd, buf, len);
...
delete[] buf;

The same thing can be done in MFC with CWnd::GetWindowText(CString&). But MFC has to use the same basic WinAPI functions, through GetBuffer. MFC's implementation of CWnd::GetWindowText is roughly as follows:

void CWnd::GetWindowText(CString &str)
{
    int nLen = ::GetWindowTextLength(m_hWnd);
    ::GetWindowText(m_hWnd, str.GetBufferSetLength(nLen), nLen+1);
    str.ReleaseBuffer();
}

Upvotes: 2

Related Questions