ReleaseBuffer resets the length of the string so that functions like GetLength() work properly. The CSimpleStringT destructor does not call ReleaseBuffer, it's just calls an internal Release which frees up the memory if the string ref count is zero. No need to call ReleaseBuffer to reset the length of the string since the string object is going away.
ReleaseBuffer should be called after GetBuffer so you can use other string functions. Presumably you use GetBuffer to put data into the string from apis that take a string buffer. After putting the data in, call ReleaseBuffer to set the length of the string. I usually match up the calls and not worry about it further. I'd rather code this way than have to remember what ReleaseBuffer does and when I really need to call it.
Here's a snippet to ponder...
CString sTest(_T("I am a test string."));
int size = sTest.GetLength(); // 19 characters
LPTSTR wz = _tcscpy(sTest.GetBuffer(35), _T("I am a larger test string: 34 chars"));
size = sTest.GetLength(); // 19 characters - oops
size = sTest.GetLength(); // 35 characters