Board index » cppbuilder » Critical memory leak in regarding String and WideString

Critical memory leak in regarding String and WideString


2007-02-22 01:00:50 AM
cppbuilder14
I was originally going to post this message to
borland.public.cppbuilder.rtl. However, due to that newsgroup's diminished
use I decided to post this message to a more frequented newsgroup.
I have run into a very critical memory leak in BCB. I have tested that this
problem exists in BCB6 and BDS2006. I believe it might have implications
beyond WideString and String but my test case only uses these two classes.
This test case shows another instance of memory leaking when a temporary
object is constructed by the compiler.
I originally ran into this issue when using the NodeName and Text properties
of _di_IXMLNode. I mention this to illustrate that the problem is more
widespread than this simple example.
To test, create a new VCL application.
struct TTest
{
WideString theText;
WideString get_Text();
TTest();
__property WideString Text = { read = get_Text };
};
TTest::TTest()
: theText(L"SOME LARGE TEXT TO MAKE THE MEMORY LEAK QUICKLY")
{
}
WideString TTest::get_Text()
{
return theText;
}
void Test(String const& Str1, String const& Str2)
{
}
Drop a Button on the form and add the following to the OnClick event
handler:
TTest test;
for (int index = 0; index < 1000; ++index)
{
Test(test.Text, test.Text); // <<-- these will leak
}
Drop a Timer on the form and add the following code to the OnTimer event
handler:
Caption = FormatFloat("#,##0", GetMemoryInUse());
Here is the code for GetMemoryInUse():
unsigned __int64 GetMemoryInUse()
{
unsigned __int64 memInUse = 0;
MEMORY_BASIC_INFORMATION mbi;
void* address = NULL;
memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION));
while (::VirtualQuery(address, &mbi, sizeof(mbi)) == sizeof(mbi))
{
if (mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE)
memInUse += mbi.RegionSize;
address = (void*) (((int) mbi.BaseAddress) + mbi.RegionSize);
memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION));
}
return memInUse;
} // GetMemoryInUse
There are three workarounds that I have found to stop the memory from
leaking. First is to perform an explicit construction rather than allowing
the compiler implicitly construct the object:
Test(String(test.Text), String(test.Text));
Second, don't declare the Test() using const-reference but simply allow
pass-by-value:
void Test(String Str1, String Str2)
This second fix works okay for String and WideString but I would still
rather enjoy the speed and minimized code benefit of using const-reference.
Third, provide a version of the function that handles WideString parameters:
void Test(WideString const& Str1, WideString const& Str2)
This also isn't the best workaround since to be sure that no memory will
leak the programmer will have to provide all permutations of the
constructor. For example:
void Test(String const& Str1, WideString const& Str2)
void Test(WideString const& Str1, String const& Str2)
- Clayton
 
 

Re:Critical memory leak in regarding String and WideString

In article <45dc7a93$ XXXX@XXXXX.COM >,
"Clayton Arends" < XXXX@XXXXX.COM >wrote:
Quote
I have run into a very critical memory leak in BCB. I have tested that this
problem exists in BCB6 and BDS2006. I believe it might have implications
beyond WideString and String but my test case only uses these two classes.
This test case shows another instance of memory leaking when a temporary
object is constructed by the compiler.
I'm added this to my to do list... Could you please QC it to make
sure that more eyes look at it?
--
-David Dean
CodeGear C++ QA Engineer
<blogs.codegear.com/ddean/>
 

Re:Critical memory leak in regarding String and WideString

Quote
Could you please QC it ...
Sure, I'll add it tomorrow. Do you have a suggestion for the correct area?
I was thinking maybe "RTL\C++\Memory Management".
- Clayton
 

{smallsort}

Re:Critical memory leak in regarding String and WideString

I have to say that WideString class is really troublesome.
After I converted in a code of mine (massively using AnsiString) AnsiStrings
to WideString my program started giving me Out of memory errors.
I had to create my own wrpper for Unicode strings and after that everything
worked fine...
 

Re:Critical memory leak in regarding String and WideString

It has some problems but I don't believe it is the primary cause of this
particular memory leak. If you reverse the String and WideString classes in
my example code the memory leaks the same way. It has something to do with
__property, getters, implicit conversion and construction, and const
reference argument passing. When I find the time today I'm hoping to
reproduce this using some other classes besides AnsiString and WideString.
If I can't figure a way to cause the leak to happen with custom classes then
it may have something to do with AnsiString/WideString implementation
afterall (or I just don't have a complete grasp on what the *real* problem).
- Clayton
 

Re:Critical memory leak in regarding String and WideString

In article < XXXX@XXXXX.COM >,
"Clayton Arends" < XXXX@XXXXX.COM >wrote:
Quote
Sure, I'll add it tomorrow. Do you have a suggestion for the correct area?
I was thinking maybe "RTL\C++\Memory Management".
That's fine. If it turns out to be caused by something else, it is
easy to recategorize it. The most important thing, IMO, is to get it in
the system in order to make sure that the issue gets tracked.
--
-David Dean
CodeGear C++ QA Engineer
<blogs.codegear.com/ddean/>
 

Re:Critical memory leak in regarding String and WideString

QC Report# 41593
- Clayton
 

Re:Critical memory leak in regarding String and WideString

I could have sworn I tried this memory leak with the AnsiString and
WideString members reversed. I just tried it again before posting my QC
entry and could not duplicate the memory leak.
However, even though a complete replacement of WideString might be in order
it isn't as simple as that. As I mentioned in the report (and in the first
post of this thread) I use IXMLDocument which makes use of WideString
properties. I also use other components which use WideString members. It
would be a huge endeavor to swap out WideString for something else. Plus,
I'm not guaranteed that the leak will go away considering there could be
other areas that I have no access to that will leak.
- Clayton
 

Re:Critical memory leak in regarding String and WideString

I was just looking through my list of submitted reports and noticed that you
placed an attachment to report# 1624 to demonstrate the problem in BDS2006.
Thank you for doing that.
I know you've heard this from myself and others before but I'll say it
again. If Code Gear is going to survive it is because of the efforts of you
and others like you that go beyond what is required. The tasks that you
took upon yourself to perform before and after you were an employee have
been noticed by the community. Your actions will most likely keep a few
more users loyal to Code Gear and also be responsible for winning a few back
in the near future -- if BDS2007 is everything we've been told to expect ;-)
Ciao for now,
- Clayton