"Out Of Memory" When using CString GetBuffer() [modified]
-
Hello all, I am trying to track down the root cause of an out of memory error when using CString GetBuffer(). I appreciate any insight or constructive criticisms of poor methods. The CString resides in an object of the "grp_vals" class: class grp_vals{ public: CStringA Name; float Vals[MAX_VALS]; float& operator [] (int Idx){ return Vals[Idx]; } }; The code where the problem arises is: LPSTR p; grp_vals *tmpvals; ... tmpvals = new grp_vals; ... p = tmpvals->Name.GetBuffer(32);//HERES WHERE THE PROBLEM STARTS fgets(p,32,FileHandle); tmpvals->Name.ReleaseBuffer(); tmpvals->Name.Remove('\n'); This code "works" for many iterations but eventually the error occurs and was traced to the "if( pNewData == NULL )" below (from the standard atlsimpstr.h)...sure enough, it's NULL but I'm not sure why only in this one case... the pOldData does not *seem* to vary from previous iterations that "worked". ATL_NOINLINE void Fork( __in int nLength ) { CStringData* pOldData = GetData(); int nOldLength = pOldData->nDataLength; CStringData* pNewData = pOldData->pStringMgr->Clone()->Allocate( nLength, sizeof( XCHAR ) ); if( pNewData == NULL ) { ThrowMemoryException(); } ....
modified on Friday, December 14, 2007 9:38:20 PM
-
Hello all, I am trying to track down the root cause of an out of memory error when using CString GetBuffer(). I appreciate any insight or constructive criticisms of poor methods. The CString resides in an object of the "grp_vals" class: class grp_vals{ public: CStringA Name; float Vals[MAX_VALS]; float& operator [] (int Idx){ return Vals[Idx]; } }; The code where the problem arises is: LPSTR p; grp_vals *tmpvals; ... tmpvals = new grp_vals; ... p = tmpvals->Name.GetBuffer(32);//HERES WHERE THE PROBLEM STARTS fgets(p,32,FileHandle); tmpvals->Name.ReleaseBuffer(); tmpvals->Name.Remove('\n'); This code "works" for many iterations but eventually the error occurs and was traced to the "if( pNewData == NULL )" below (from the standard atlsimpstr.h)...sure enough, it's NULL but I'm not sure why only in this one case... the pOldData does not *seem* to vary from previous iterations that "worked". ATL_NOINLINE void Fork( __in int nLength ) { CStringData* pOldData = GetData(); int nOldLength = pOldData->nDataLength; CStringData* pNewData = pOldData->pStringMgr->Clone()->Allocate( nLength, sizeof( XCHAR ) ); if( pNewData == NULL ) { ThrowMemoryException(); } ....
modified on Friday, December 14, 2007 9:38:20 PM
My understanding from the MSDN docs on ReleaseBuffer() is that the memory that "p" points to is freed (invalidated), but when running in debug I can see that this is not the case. Is it possible that I am filling up memory by not explicitly freeing the memory that "p" points to before assigning it to a new string via GetBuffer()? Or is this a side-effect of running in debug mode?
-
My understanding from the MSDN docs on ReleaseBuffer() is that the memory that "p" points to is freed (invalidated), but when running in debug I can see that this is not the case. Is it possible that I am filling up memory by not explicitly freeing the memory that "p" points to before assigning it to a new string via GetBuffer()? Or is this a side-effect of running in debug mode?
-
Hello all, I am trying to track down the root cause of an out of memory error when using CString GetBuffer(). I appreciate any insight or constructive criticisms of poor methods. The CString resides in an object of the "grp_vals" class: class grp_vals{ public: CStringA Name; float Vals[MAX_VALS]; float& operator [] (int Idx){ return Vals[Idx]; } }; The code where the problem arises is: LPSTR p; grp_vals *tmpvals; ... tmpvals = new grp_vals; ... p = tmpvals->Name.GetBuffer(32);//HERES WHERE THE PROBLEM STARTS fgets(p,32,FileHandle); tmpvals->Name.ReleaseBuffer(); tmpvals->Name.Remove('\n'); This code "works" for many iterations but eventually the error occurs and was traced to the "if( pNewData == NULL )" below (from the standard atlsimpstr.h)...sure enough, it's NULL but I'm not sure why only in this one case... the pOldData does not *seem* to vary from previous iterations that "worked". ATL_NOINLINE void Fork( __in int nLength ) { CStringData* pOldData = GetData(); int nOldLength = pOldData->nDataLength; CStringData* pNewData = pOldData->pStringMgr->Clone()->Allocate( nLength, sizeof( XCHAR ) ); if( pNewData == NULL ) { ThrowMemoryException(); } ....
modified on Friday, December 14, 2007 9:38:20 PM
How are you handling string length? If the data you read into the string buffer is NULL terminated, you're OK. If the data is not NULL terminated, then you should be specifying the actual string length when you call ReleaseBuffer(). Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
How are you handling string length? If the data you read into the string buffer is NULL terminated, you're OK. If the data is not NULL terminated, then you should be specifying the actual string length when you call ReleaseBuffer(). Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
Thanks, Fortunately it was as simple as replacing '\n' with '\0' in "p" before ReleaseBuffer(). Unfortunately, my problem has just moved somwhere else, which I'm guessing means that I have other memory leak issues to deal with... That's ok, I'm sure it builds character or something like that...
-
Thanks, Fortunately it was as simple as replacing '\n' with '\0' in "p" before ReleaseBuffer(). Unfortunately, my problem has just moved somwhere else, which I'm guessing means that I have other memory leak issues to deal with... That's ok, I'm sure it builds character or something like that...
nadiric wrote:
That's ok, I'm sure it builds character or something like that...
I like to think so :) Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java: