Reputation: 877
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
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
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