Tipy a triky v Delphi, díl 98.

Diskuze čtenářů k článku

Aleš Pavel  |  19. 05. 2004 15:05

procedure TForm1.Button2Click(Sender: TObject);
var
  ms1, ms2: TMemoryStream;
begin
try

    ms1 := TMemoryStream.Create;
    ms2 := TMemoryStream.Create;
    ms1.LoadFromFile(`C:\test.dat`);
    DecompressStream(ms1, ms2);
    RichEdit1.Lines.LoadFromStream(ms2);
  finally
    ms1.Free;
    ms2.Free;
  end;
end;

Takhle to ma vypadat co vyvadite??? Myslete hlavou...

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petr Zedník  |  09. 07. 2003 10:24

Já bych použil pouze jeden blok try:

procedure TForm1.Button2Click(Sender: TObject);
var
  ms1, ms2: TMemoryStream;
begin
  ms1 := TMemoryStream.Create;
  ms2 := TMemoryStream.Create;
  try
    ms1.LoadFromFile(`C:\test.dat`);
    DecompressStream(ms1, ms2);
    RichEdit1.Lines.LoadFromStream(ms2);
  finally
    ms1.Free;
    ms2.Free;
  end;
end;


Jinak samozřejmě supr užitečný tip.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Boris Letocha  |  09. 07. 2003 12:03

No, ale je to opravdu JEN podle tebe.

Co myslis, ze se stane, kdyz ms2 := TMemoryStream.Create; se nepovede kvuli nedostatku pameti?

Odpovim ti: Budes tam mit memory leak. Tohle ms1 := TMemoryStream.Create; uz se nikdy neuvolni.

Tohle je prave problem Pascalu, nema autopointery a ani GC a tak se to musi, aby to bylo safe psat takhle zdlouhave. I kdyz finally je rozhodne uzitecna vec a v C++ znatelne chybi.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petr Zedník  |  09. 07. 2003 12:13

To je pravda, takže můj návrh není správně, ale z tohoto pohledu není v příkladu v článku ošetřen už ani první Create (ms1 := TMemoryStream.Create), protože ošetřeno je přece jen to co je uvnitř bloku try nebo se mýlím?

Souhlasím  |  Nesouhlasím  |  Odpovědět
Boris Letocha  |  09. 07. 2003 12:40

Jo ted jsem si vsiml, ze to autor prece jen ma spatne, ve finally blocich prohodil ms1 s ms2. Vnitrni blok musi uvolnovat ms2 a vnejsi ms1.

Jinak k tomu tvemu: pokud .Create vyhodi vyjimku, tak uz je zaruceno, ze se nic uvolnovat nemusi. Ono by to ani taky neslo, protoze v pripade vyjimky v Create nedojte ani k tomu prirazeni a pointer by obsahoval "nahodne data"

Mozna tedy optimalni by bylo napsat v Delphach toto:

procedure TForm1.Button2Click(Sender: TObject);
var
  ms1, ms2: TMemoryStream;
begin
  ms1 := TMemoryStream.Create;
  ms2 := nil;
  try
    ms2 := TMemoryStream.Create;
    ms1.LoadFromFile(`C:\test.dat`);
    DecompressStream(ms1, ms2);
    RichEdit1.Lines.LoadFromStream(ms2);
  finally
    ms1.Free;
    ms2.Free;
  end;
end;

Free totiz po zavolani na nil nedela nic.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Doooca  |  09. 07. 2003 16:40

"Free totiz po zavolani na nil nedela nic."

A to jako od kdy? 

Souhlasím  |  Nesouhlasím  |  Odpovědět
Boris Letocha  |  09. 07. 2003 18:16

No urcite alespon od Delphi 2.0

cituji z http://bdn.borland.com/article/0,1410,10325,00.html:

Most of TObjects methods are used internally by the VCL. You will primarily call the Create and Free methods. One caution: try to use the Free method instead of calling the Destroy destructor directly when freeing an object instance. Free is a bit safer to use because it first checks to make sure the component instance is not Nil before destroying it.

A urcite by se to dalo najit i v tomto serialu.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Zasílat názory e-mailem: Zasílat názory Můj názor