|
-
April 10th, 2004, 05:41 PM
#1
Memory Leaks deleting ptr to TCHAR[]'s inside CPtrArray
Hi
I'm trying to store many TCHAR strings as dynamically created on the heap as pointers inside a CArray (CTypedPtrArray<CPtrArray,TCHAR*>).
I made a small class to wrap it all as below. However when I come to clean up after deleting the class it reports each string as a leak, even though I did the delete on it.
Any Ideas?
Header
Code:
class CTextContainerArray : public CTypedPtrArray<CPtrArray,TCHAR*>
{
// Construction
public:
CTextContainerArray();
~CTextContainerArray();
void AddString(TCHAR* pStr,int len);
};
Body
Code:
CTextContainerArray::CTextContainerArray(){}
CTextContainerArray::~CTextContainerArray()
{
TCHAR* pText;
for (int j =0; j < GetSize(); j++)
{
pText = (TCHAR*)GetAt(j);
if(pText)
{
delete [] pText;
}
}
RemoveAll();
}
void CTextContainerArray::AddString(TCHAR* pStr,int len)
{
TCHAR* newstr = NULL;
if ((len > 0) && pStr)
{
newstr = new TCHAR[len];
if (newstr)
{
wcscpy(newstr,pStr);
}
}
Add(newstr);
}
Sample of Memory leak output:
{9904} normal block at 0x011AD6E8, 64 bytes long.
Data: < C| > B8 AE 43 7C 17 00 00 00 17 00 00 00 01 00 00 00
{9903} normal block at 0x011AD688, 30 bytes long.
Data: < C| > B8 AE 43 7C 06 00 00 00 06 00 00 00 01 00 00 00
{9902} normal block at 0x011AD608, 64 bytes long.
Data: < C| > B8 AE 43 7C 17 00 00 00 17 00 00 00 01 00 00 00
{9901} normal block at 0x011AD5A8, 30 bytes long.
Something else that was quite interesting, is that previous to the version above. I allocated the memory for the string separately, copied the string into the new memory location given by new. Then used the CArray->Add member to simply add the pointer to the allocated string. This also leaked. But the leak was the actual string memory location. IE you could see the text in the leak print out!
Do I need to write my own heap manager functions and use my own heap area? Or am I doing something really silly?
Also does it matter that this class is created in a worker thread of a CDoculent? The class is then added to another CArray. I haven't had any problems with these.
-
April 10th, 2004, 06:10 PM
#2
When you call AddString(), what do you pass as the
length ? the wcslen() or wcslen() + 1 ? i.e. In AddString()
are you allocating space for the trailing NULL ?
-
April 10th, 2004, 06:31 PM
#3
Also does it matter that this class is created in a worker thread of a CDoculent?
Sure ! If you want to see if the class is causing a leak, drop it
into a console, or some similar simple app, and see if it leaks
there. I'll bet this one doesn't ( I checked ). Just because the
output window shows a leak that doesn't mean theres a leak -
just that at that time there seems to be.
And why pass in the len to AddString() - can't AddString() figure
that out itself leaving the caller to do less work ?
-
April 10th, 2004, 06:45 PM
#4
I don't understand why you wouldn't use an array that has been designed to handle string arrays, CStringArray.
An alternative would be vector<string>
Steve
-
April 10th, 2004, 07:15 PM
#5
Thanks for the answers guys.
Philip:
I'm using wcslen(). So I think your hunch must be correct. I'll check in a minute or two.
mdmd:
The only excuse I can think of for not noticing that I don't need to pass in the length of the string is that maybe one day I'll need a class that can handle both strings, and arrays of unsigned shorts. Until I remove it a few minutes. I'll stand by it.
Steve:
The reason I was trying this is to speed up the loading of my program. The CStrings I feel are just an uncessesary overhead. The code runs on XP, and also windows CE 3.0. The CE machine is only 166Mhz! After loading a few thousand small CStrings from a text file a lot of time has gone past.
However, the main reason I'm reducing the CString usage is becuase I think my program is suffering from memory fragmentation caused by the constant resizing of the CStrings. It's very noticeable on the wince machine after about 10 or so hours continuous running. The strings loaded into this class are never modified, so why even need them in a CString? In other places I'm trying to use fixed length buffers instead of CStrings, and I'll maybe port the CStr class to unicode that's around in the projects somewhere (or is that codeproject?). It has it's own heap memory management apparently.
Oh and as my class isn't working it's currently commented out, and I've typedef'd CTextContainer to a CStringArray, and a small change where I called AddString(). 
vector<string>? STL isn't supported on Wince 3.0
-
April 10th, 2004, 07:45 PM
#6
-
April 11th, 2004, 12:59 AM
#7
Memory leaks should always be eliminated in my opinion - no matter how small.
Consider that for a particular operation only 2 bytes are leaked. However, if this operation is done 100 times a second that means it is leaking 200 bytes per second ! Eventually your program will terminate because of this.
So I would seriously try to eliminate the leak.
Oh and by the way it seems that you're not deleting your thread correctly. Are you using manual or auto delete of the thread ? There's a member in the CWinThread class called m_bAutoDelete or something which tells it whether to delete itself when it exits.
Set this in the constructor to being 1 and all should be fine then.
Darwen.
Last edited by darwen; April 11th, 2004 at 01:02 AM.
-
April 11th, 2004, 11:03 AM
#8
Interesting problem and you seem to have solved most of your difficulty.
If none of these strings are modified, you might try another approach. Depending on what your program does with the data, this may or may not be practical. Read in all the "strings" at once as one memory block. Before you read in the strings block, read in an array of indexes which are a map into the strings block. The last value in the index array is the length of the last "string".
Steve
Steve
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|