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).
| Вернуться в корень Архива |