Memory leak with CString
-
I have found a very interesting incident of memory leak in my code. Although I have not been able to find the root cause of the leak still thought to share with you all. I will really appreciate any help on this. I am rather curious to know how come a memory leak can be seen in use of CString in such a simple way. Code: We have a thread function:
UINT __cdecl LogWriteThread(void *pParam)
{
CLog* pLog = (CLog*)pParam;
UNUSED_ALWAYS(pParam);
try
{
pLog->LogWriteFunc();
}
.................
.................
return 0;
}UINT __cdecl CLog::LogWriteFunc(void *pParam)
{
..........
CString cstrLogDataBuffer = m_cstrLogLine;
m_cstrLogLine = _T("");
CopyLogToFileByThread(cstrLogDataBuffer);
}void CMpmLog::CopyLogToFileByThread(const CString& cstrLogDataBuffer)
{
....................
const long iLength = cstrLogDataBuffer.GetLength();
char *pBuffer = new char[iLength + 1];
for (long iIndex = 0;iIndex < iLength; iIndex++)
{
pBuffer[iIndex] = (char)cstrLogDataBuffer.GetAt(iIndex);
}
pBuffer[iLength] = '\0';const unsigned int uiWriteLen = fwrite((const void \*)pBuffer, sizeof(char),iLength, m\_pofLogStream); delete\[\] pBuffer; ....................
}
======================== If I commment call for "CopyLogToFileByThread" in function LogWriteFunc then memory leak goes away. But thats not the solution.
Manoj Never Gives up
-
I have found a very interesting incident of memory leak in my code. Although I have not been able to find the root cause of the leak still thought to share with you all. I will really appreciate any help on this. I am rather curious to know how come a memory leak can be seen in use of CString in such a simple way. Code: We have a thread function:
UINT __cdecl LogWriteThread(void *pParam)
{
CLog* pLog = (CLog*)pParam;
UNUSED_ALWAYS(pParam);
try
{
pLog->LogWriteFunc();
}
.................
.................
return 0;
}UINT __cdecl CLog::LogWriteFunc(void *pParam)
{
..........
CString cstrLogDataBuffer = m_cstrLogLine;
m_cstrLogLine = _T("");
CopyLogToFileByThread(cstrLogDataBuffer);
}void CMpmLog::CopyLogToFileByThread(const CString& cstrLogDataBuffer)
{
....................
const long iLength = cstrLogDataBuffer.GetLength();
char *pBuffer = new char[iLength + 1];
for (long iIndex = 0;iIndex < iLength; iIndex++)
{
pBuffer[iIndex] = (char)cstrLogDataBuffer.GetAt(iIndex);
}
pBuffer[iLength] = '\0';const unsigned int uiWriteLen = fwrite((const void \*)pBuffer, sizeof(char),iLength, m\_pofLogStream); delete\[\] pBuffer; ....................
}
======================== If I commment call for "CopyLogToFileByThread" in function LogWriteFunc then memory leak goes away. But thats not the solution.
Manoj Never Gives up
The shown code part of
CopyLogToFileByThread()
does not change aCString
object. So this can't be the source of the leak it is from aCString
object. It seems that you are accessing them_strLogLine
CString
object by multiple threads. When doing so, you must use locking. To do so, you may add aCCriticalSection
member to your class and use this for locking:CSingleLock singleLock(&m_CritSection);
singleLock.Lock();
CString cstrLogDataBuffer = m_cstrLogLine;
m_cstrLogLine = _T("");
singleLock.Lock();Use similar code when changing or reading
m_strLogLine
anywhere. One more note: Instead of converting aTCHAR
string tochar
by casting each char, you may useWideCharToMultiByte()
or the conversion provided byCString
:// This converts a TCHAR string to char string
CStringA strLineA(cstrLogDataBuffer.GetString());
fwrite(strLineA.GetString(), sizeof(char), strLineA.GetLength(), m_pofLogStream); -
The shown code part of
CopyLogToFileByThread()
does not change aCString
object. So this can't be the source of the leak it is from aCString
object. It seems that you are accessing them_strLogLine
CString
object by multiple threads. When doing so, you must use locking. To do so, you may add aCCriticalSection
member to your class and use this for locking:CSingleLock singleLock(&m_CritSection);
singleLock.Lock();
CString cstrLogDataBuffer = m_cstrLogLine;
m_cstrLogLine = _T("");
singleLock.Lock();Use similar code when changing or reading
m_strLogLine
anywhere. One more note: Instead of converting aTCHAR
string tochar
by casting each char, you may useWideCharToMultiByte()
or the conversion provided byCString
:// This converts a TCHAR string to char string
CStringA strLineA(cstrLogDataBuffer.GetString());
fwrite(strLineA.GetString(), sizeof(char), strLineA.GetLength(), m_pofLogStream);Thanks Jochen for your inputs. 1. I have used CriticalSection while accessing m_cstrLogLine but have omitted those additional lines to focus on actual business logic. 2. I agree that WideCharToMultiByte() could have been a better option to convert string but I have changed code to rule out any leak during conversion itself. 3. The CopyLogToFileByThread() is not modifying string and thats why its surprising to have memory leak from that function. 4. One more point i will like to mention here is thhat this application has been built for WinCE 6.0. I am trying to replicate the same issue with a test application and if possible for XP.
Manoj Never Gives up
-
I have found a very interesting incident of memory leak in my code. Although I have not been able to find the root cause of the leak still thought to share with you all. I will really appreciate any help on this. I am rather curious to know how come a memory leak can be seen in use of CString in such a simple way. Code: We have a thread function:
UINT __cdecl LogWriteThread(void *pParam)
{
CLog* pLog = (CLog*)pParam;
UNUSED_ALWAYS(pParam);
try
{
pLog->LogWriteFunc();
}
.................
.................
return 0;
}UINT __cdecl CLog::LogWriteFunc(void *pParam)
{
..........
CString cstrLogDataBuffer = m_cstrLogLine;
m_cstrLogLine = _T("");
CopyLogToFileByThread(cstrLogDataBuffer);
}void CMpmLog::CopyLogToFileByThread(const CString& cstrLogDataBuffer)
{
....................
const long iLength = cstrLogDataBuffer.GetLength();
char *pBuffer = new char[iLength + 1];
for (long iIndex = 0;iIndex < iLength; iIndex++)
{
pBuffer[iIndex] = (char)cstrLogDataBuffer.GetAt(iIndex);
}
pBuffer[iLength] = '\0';const unsigned int uiWriteLen = fwrite((const void \*)pBuffer, sizeof(char),iLength, m\_pofLogStream); delete\[\] pBuffer; ....................
}
======================== If I commment call for "CopyLogToFileByThread" in function LogWriteFunc then memory leak goes away. But thats not the solution.
Manoj Never Gives up
Manoj Kumar Rai wrote:
I have found a very interesting incident of memory leak in my code.
How are you verifying this?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous