Что, если я не вызову ReleaseBuffer после GetBuffer?

От CString до char* после GetBuffer() необходимо использовать ReleaseBuffer(). Но почему? Что произойдет, если я не буду использовать ReleaseBuffer() после GetBuffer()?

Может ли кто-нибудь показать мне пример? Спасибо.


person Landy    schedule 26.02.2010    source источник


Ответы (4)


Я не уверен, что это приведет к утечке памяти, но вы должны вызвать ReleaseBuffer, чтобы убедиться, что закрытые члены CString обновлены. Например, ReleaseBuffer обновит поле длины CString, ища завершающий символ null.

person Nick Meyer    schedule 26.02.2010
comment
@Ник, спасибо. Я только что написал небольшую программу для тестирования ReleaseBuffer(), вы правы!! Спасибо! - person Landy; 26.02.2010
comment
Согласно документации Microsoft: если вы используете указатель, возвращенный GetBuffer, для изменения содержимого строки, вы должны вызвать ReleaseBuffer перед использованием любых других функций-членов CString. Т.е. вам не всегда нужно использовать их парами. - person SamWhan; 12.04.2018
comment
@SamWhan, если вы не собираетесь изменять содержимое строки, вам следует вместо этого использовать указатель const, для которого не требуется GetBuffer - просто приведение к PCTSTR. - person Mark Ransom; 28.02.2019

Что произойдет, если я не буду использовать ReleaseBuffer() после GetBuffer()?

Я не использовал MFC (и, надеюсь, мне никогда не придется касаться его десятифутовым шестом), но, как правило, всякий раз, когда у вас есть API, который имеет как GetXXX(), так и ReleaseXXX() (особенно когда результат GetXXX() удобно относится к типу, который принимает ReleaseXXX()) -- тогда, когда вы забываете вызывать ReleaseXXX() для каждого из ваших вызовов GetXXX(), вы пропускаете XXX.

person sbi    schedule 26.02.2010
comment
@sbi, спасибо. Из этого поста - stackoverflow.com/questions/559483/cstring-to-char, вызывая метод GetBuffer не приведет к утечкам памяти. Потому что деструктор все равно освободит буфер. - person Landy; 26.02.2010
comment
@Лэнди: Ну вот. Так что в данном случае эмпирическое правило не работает. Наверное, поэтому это и называется эмпирическим правилом, нет? Я разве говорил, что не люблю MFC? Теперь есть еще одна причина сделать это. API, в котором GetXXX() и ReleaseXXX() не идут парами, просто отстой... Во всяком случае, из msdn.microsoft.com/en-us/library/awkwbzyc.aspx: после непосредственного изменения содержимого объекта CString необходимо вызвать ReleaseBuffer перед вызовом любых других функций-членов CString. - person sbi; 26.02.2010
comment
Спасибо. MSDN говорит, что после непосредственного изменения содержимого объекта CString необходимо вызвать ReleaseBuffer, прежде чем вызывать любые другие функции-члены CString. Но MSDN не говорит, почему я должен вызывать ReleaseBuffer. В сообщении Ника он сказал, что ReleaseBuffer() обновит поле длины CString. Я думаю, это хорошая причина. Спасибо. - person Landy; 26.02.2010
comment
Исходный код CString доступен в файле atlsimplestr.h. Выполняя отладку, я вижу, что CSring::ReleaseBuffre() устанавливает только длину строки и не выполняет освобождение, выделение или перераспределение памяти. nDataLength из CStringData (используется внутри CString) содержит длину строки. nAllocLength содержит длину буфера. BufferRelase изменяет только nDataLength. Даже не касается nAllocLength . Я чувствую, что это случай двусмысленности в имени функции в сочетании с ужасной документацией, в которой MS хороша, к счастью, у нас есть исходный код (к сожалению, который MS может изменить в любое время). - person Sahil Singh; 23.12.2018

Вот пример того, как я использовал CString::GetBuffer() и CString::ReleaseBuffer() :

LPTSTR pUnitBuffer = pAPBElement->m_strUnits.GetBuffer(APB_UNIT_SIZE);
if (pUnitBuffer != "")
{
   if (strncmp(pAPBElement->m_strUnits, (char*)pszBuffer[nLoop - nFirst], APB_UNIT_SIZE) != 0)
   {    
     LPTSTR pUnitOriginal = pAPBElement->m_strOriginal.GetBuffer(APB_UNIT_SIZE);

     strncpy(pUnitBuffer, 
            (char*)&pszBuffer[nLoop - nFirst], 
            APB_UNIT_SIZE);

     strncpy(pUnitOriginal, 
            (char*)&pszBuffer[nLoop - nFirst], 
            APB_UNIT_SIZE);

     pAPBElement->m_strOriginal.ReleaseBuffer();
    }
}
pAPBElement->m_strUnits.ReleaseBuffer();
person Jim Lahman    schedule 01.03.2012

Если вы не изменяете содержимое CString с помощью указателя, полученного с помощью GetBuffer(), вам НЕ нужно впоследствии вызывать ReleaseBuffer()

person BruceCoder    schedule 19.06.2019