Home > Software engineering >  Can CStringList increase memory and never freed until closed the application
Can CStringList increase memory and never freed until closed the application

Time:08-24

I have an application which runs slower during the time (remarkable after days).
I still have no clue, where this is coming, but I see in Taskmanager, the app is constantly consume more memory (working set and commmit size).

I have special Traces to visualize Traces to differents OutputPanes. I do this by simply add Traces to one and more different CStringList. Like this code example

//////////////////////////////////////////////////////////////////////////
//  TRACE HW_MESSAGES
void TRACE_HW(LPCTSTR pszstring)
{
  CHwTestApp* pApp = &theApp;
  if (pApp)
    return;

  TRACE(pszstring);     

  if (theApp.mStrHwList.GetCount() > kMAXTRACEs)    
  {
    CString ob = theApp.mStrHwList.RemoveHead();
  }
  theApp.mStrHwList.AddTail(pszstring);
  
}

My question can CStringList become more ane more greater by calling RemoveHead and AddTail?
Does he compact at once internally his used physically memory or delayed?

CodePudding user response:

The code posted will not leak memory. The specific CStringList overload for RemoveHead() passes ownership out of the container, and the local ob object gets immediately destroyed.

AddTail() makes a CString copy of the passed in character string pointer, and passes that copy into the CStringList. You can thus run the following code indefinitely, without the memory increasing:

while (true) {
    CString str = _T("Test trace entry");
    TRACE_HW(str.GetString());
}

The crucial point here is that TRACE_HW will not assume ownership of the memory pointed to by pszstring. So long as the caller makes sure to clean that up, everything is fine (this is what the local CString object does).

If, however, you change that to the following:

while (true) {
    TCHAR* str = new TCHAR[256];
    TRACE_HW(str);
}

things are starting to change. This is allocating memory, passes a pointer into TRACE_HW which merely observes the memory, but then no-one is ever cleaning that up.

All things being equal, the issue is with the caller of TRACE_HW, not TRACE_HW itself.


Well, sort of, anyway. The function signature of TRACE_HW certainly invites clients into assuming that they're passing off ownership. Pointer arguments in C generally model transfer of ownership. If you want to express the property of being an observer only, a const reference is more appropriate.

If TRACE_HW had the following signature instead:

void TRACE_HW(CString const& msg)

it would be far more obvious to clients that they retain responsibility for the object passed off to the interface for inspection only. When the call expires, they're still responsible for dealing with the actual object.

CodePudding user response:

CString ob = ... is destroyed immediately at the scope. Therefore, it isn't the leak cause.

https://docs.microsoft.com/en-us/windows/win32/directshow/cgenericlist-removehead

According to this however, RemoveHead returns an OBJECT*. Where does that go? It's duplicated by CString all right, but the original OBJECT* is left unowed?

  • Related