CStatusBar::SetPaneText() leaks...
Marvin Hymowech -- Marvin_Hymowech@msn.com
Sunday, July 21, 1996
Environment: VC4.2, Win95
Calling CStatusBar::SetPaneText(id, "") causes a memory leak under
VC4.2 (but did not under VC4.1). This is apparently due to the
following:
1. In VC4.2, the indicated lines were added to CString::Empty():
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void CString::Empty()
{
>> if (GetData()->nDataLength == 0) // added
>> return; // added
if (GetData()->nRefs >= 0)
Release();
else
*this = &afxChNil;
ASSERT(GetData()->nDataLength == 0);
ASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
On the one hand, this seems like a harmless optimization (why
empty a string which is already empty?), but in fact breaks the
stated semantics of CString::Empty() (quoting from the VC4.2 help
for CString::Empty()): "Makes this CString object an empty string
and frees memory as appropriate."
2. Unfortunately, there is at least one place in MFC which
depended upon this behavior (quoting from barstat.cpp);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CStatusBar::~CStatusBar()
{
AllocElements(0, 0); // destroys existing elements
}
BOOL CStatusBar::AllocElements(int nElements, int cbElement)
{
// destruct old elements
AFX_STATUSPANE* pSBP = _GetPanePtr(0);
for (int i = 0; i < m_nCount; i++)
{
pSBP->strText.Empty();
++pSBP;
}
// allocate new elements
if (!CControlBar::AllocElements(nElements, cbElement))
return FALSE;
// construct new elements
pSBP = _GetPanePtr(0);
for (i = 0; i < m_nCount; i++)
{
>> memcpy(&pSBP->strText, &afxEmptyString, sizeof(CString));
++pSBP;
}
return TRUE;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
As you can see, the author(s) of CStatusBar never bothered to call
CString::~CString(), prefering instead to rely upon the stated
behavior of EmptyString(), and simply overlaying their instances
with a known instance of an empty string.
A simple workaround in this case was simply to call
CStatusBar::SetPaneText(id, " "), providing a one-character blank
string instead - now CString::Empty() will actually delete the memory.
Does anyone know of other instances in MFC where this modification to
EmptyString() is causing leaks?
- Marvin Hymowech
John & Annette Elsbree -- elsbree@msn.com
Thursday, July 25, 1996
Marvin -
Thanks for the report. I just so happens that someone reported this same bug
to us last Friday (the day before your message).
Needless to say, we'll fix this one in an upcoming release.
John ("not speaking for Microsoft") Elsbree
----------
From: owner-mfc-l@netcom.com on behalf of Marvin Hymowech
Calling CStatusBar::SetPaneText(id, "") causes a memory leak under
VC4.2 (but did not under VC4.1).
| Вернуться в корень Архива
|