4
\$\begingroup\$

With Delphi 7 I need to create a TStream variable and use/free it in another part of the code. Unfortunately it cannot be passed as "normal" parameter.

I created a simple application for testing what I need, using some examples I found on Google and some help from SOF (I am not used to pointers).

Here is what I got so far (it uses an Edit, a Memo e 3 Buttons):

function IsObject(Address: Pointer): Boolean; assembler;
asm
  MOV     EAX, [Address]
  CMP     EAX, EAX.vmtSelfPtr
  JNZ     @False
  MOV     Result, True
  JMP     @Exit
@False:
  MOV     Result, False
@Exit:
end;

procedure TForm1.btnSetMem1Click(Sender: TObject);
var
  Stm: TStream;
begin
  Stm := TMemoryStream.Create;
  edtMemID1.Text := IntToStr(Integer(Stm));
end;

procedure TForm1.btnSaveMem1Click(Sender: TObject);
var
  Stm: TStream;
begin
  Stm := Pointer(StrToInt(edtMemID1.Text));
  if IsObject(Stm) then
  try
    memStm1.Lines.SaveToStream(Stm);
    btnSaveMem1.Enabled := False;
    btnLoadMem1.Enabled := True;
    memStm1.Clear;
  except
    FreeAndNil(Stm);
  end;
end;

procedure TForm1.btnLoadMem1Click(Sender: TObject);
var
  Stm: TStream;
begin
  Stm := Pointer(StrToInt(edtMemID1.Text));
  if IsObject(Stm) then
  try
    Stm.Position := 0;
    memStm1.Lines.LoadFromStream(Stm);
  except
    FreeAndNil(Stm);
  end;
end;

procedure TForm1.btnFreeMem1Click(Sender: TObject);
var
  Stm: TStream;
begin
  Stm := Pointer(StrToInt(edtMemID1.Text));
  if IsObject(Stm) then FreeAndNil(Stm);
  btnSaveMem1.Enabled := False;
  btnLoadMem1.Enabled := False;
  edtMemID1.Clear;
end;

procedure TForm1.edtMemID1Change(Sender: TObject);
begin
  btnSaveMem1.Enabled := (Trim(edtMemID1.Text) <> '');
  btnFreeMem1.Enabled := (Trim(edtMemID1.Text) <> '');
end;

The ASM function I found here and seems to be working. I also tested with FastMM and there is no memory leak (if btnFreeMem is used).

Please review this code and maybe give some tips to make it better or avoid problems (memory leaks).

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There is not much to be reviewed here.

Function IsObject does it's job correctly and there is not much to be said there.

What would have to be reviewed is the real code that would need IsObject and memory management technique you have shown in your demo. Since your demo is just a demo it doesn't show real life issue you are trying to resolve, and therefore it is impossible to give you any tips and advice on how to improve it.

All I can say is don't ever manage memory like that, and if you really, really feel the need to do so, then post such code here for review. Unless you have some real corner case there, I am quite sure that such code can be thoroughly reviewed and refactored.

So, your code is perfectly fine except you should not be using it anywhere :)

\$\endgroup\$
3
  • \$\begingroup\$ Thank you for you answer @DalijaPrasnikar. I will try to implement this on the main project and add more code to question if necessary. Thank you again! \$\endgroup\$
    – Guybrush
    Jul 23, 2015 at 12:00
  • \$\begingroup\$ I think that asking new question would be more appropriate in this case. \$\endgroup\$ Jul 23, 2015 at 12:07
  • \$\begingroup\$ Like I said, the code you posted works fine and cannot be improved on its own. If you really have to manage memory in such way, code you have posted is OK, but I would highly recommend avoiding need for such memory management in the first place. \$\endgroup\$ Jul 23, 2015 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.