Page 1 of 1

GetTextOrDefaultC: freeing memory?

Posted: Mon Nov 13, 2006 1:26 pm
by khs
Hi there,

just a short question: how/when is freeing the memory which seems to be allocated by GetTextOrDefaultC done, or do I do it myself? Trying to track down an AV here...

Greetings,
khs

Posted: Mon Nov 13, 2006 2:53 pm
by isiticov
You need to free it by yourself and you can free it right after the usage.

...

Posted: Mon Nov 13, 2006 3:54 pm
by khs
Using plain delete[]?

...

Posted: Mon Nov 13, 2006 4:24 pm
by khs
I think I have found the source of the AV.

The GetTextOrDefault functions take "const AnsiString" as an argument, meaning in C++Builder a temporary AnsiString is constructed out of whatever parameter is passed. However, previous versions of Builder are buggy when handling temporaries. This code:

Code: Select all

char *foo[2]={"", somefunc("IDS_0")}
, with

Code: Select all

char *somefunc(const AnsiString bar) { return "foo"; }
produces the following asm:

1) delete some yet-unconstructed AnsiString
2) construct a temporary AnsiString from "IDS_0"
3) call somefunc for the temporary AnsiString
4) forget about the temporary AnsiString

I tried it with the express version of Turbo C++, and the sequence is the correct one: construct, call, delete. However, using Builder4 with the bcc32 5.5.1 from the free commandline tools produces the potentially AVing code. Also if AnsiString is replaced with std::string.

Posted: Mon Nov 13, 2006 6:11 pm
by isiticov
The following code:

Code: Select all

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char * Temp = siLang1->GetTextOrDefaultC("IDS_0" /* "Some test string" */ );
  char Temp2[100];
  sprintf(Temp2, "%s", Temp);
  delete Temp;
  ShowMessage(Temp2);
}
works fine under C++Builder 4. I didn't check the generated ASM code. But at least there is no AV generated.

...

Posted: Mon Nov 13, 2006 7:04 pm
by khs
Yes, in general using GetTextOrDefault only in very simple constructs seems to be a good idea. Or updating to Turbo C++... ;)

So is delete[] ok for the returned char *?

Posted: Tue Nov 14, 2006 3:50 am
by isiticov
Yes, I think so.

...

Posted: Tue Nov 14, 2006 12:57 pm
by khs
Just found this totally by chance:

http://qc.borland.com/wc/qcmain.aspx?d=668

So it seems we have a neatly isolated problem here.

...

Posted: Tue Nov 14, 2006 1:00 pm
by khs
... that has to do with buggy handling of temporary objects used during the construction of arrays.

test

Posted: Tue Nov 14, 2006 2:05 pm
by khs
Also, the code that is produced for

Code: Select all

MessageBox(0, siLang1->GetTextOrDefault("IDS_xx").c_str(), siLang1->GetTextOrDefault("IDS_yy").c_str(), MB_OK);
seems fine: first twice { construction of parameter-AnsiString and result-AnsiString, call to GetTextOrDefault }, then the MessageBox, then destruction of all 4 AnsiStrings. And it's without delete[] too.

Posted: Tue Nov 14, 2006 2:39 pm
by isiticov
Yes, because you deal with AnsiString returned by GetTextOrDefault() :)
So you can use it in this way.