15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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).




| Вернуться в корень Архива |