Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
224 views
in Technique[技术] by (71.8m points)

How to properly free records that contain various types in Delphi at once?

type
  TSomeRecord = Record
    field1: integer;
    field2: string;
    field3: boolean;
  End;
var
  SomeRecord: TSomeRecord;
  SomeRecAr: array of TSomeRecord;

This is the most basic example of what I have and since I want to reuse SomeRecord (with certain fields remaining empty, without freeing everything some fields would be carried over when I'm reusing SomeRecord, which is obviously undesired) I am looking for a way to free all of the fields at once. I've started out with string[255] and used ZeroMemory(), which was fine until it started leaking memory, that was because I switched to string. I still lack the knowledge to get why, but it appears to be related to it being dynamic. I am using dynamic arrays as well, so I assume that trying ZeroMemory() on anything dynamic would result in leaks. One day wasted figuring that out. I think I solved this by using Finalize() on SomeRecord or SomeRecAr before ZeroMemory(), but I'm not sure if this is the proper approach or just me being stupid.

So the question is: how to free everything at once? does some single procedure exist at all for this that I'm not aware of?

On a different note, alternatively I would be open to suggestions how to implement these records differently to begin with, so I don't need to make complicated attempts at freeing stuff. I've looked into creating records with New() and then getting rid of it Dispose(), but I have no idea what it means when a variable after a call to Dispose() is undefined, instead of nil. In addition, I don't know what's the difference between a variable of a certain type (SomeRecord: TSomeRecord) versus a variable pointing to a type (SomeRecord: ^TSomeRecord). I'm looking into the above issues at the moment, unless someone can explain it quickly, it might take some time.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Assuming you have a Delphi version that supports implementing methods on a record, you could clear a record like this:

type
  TSomeRecord = record
    field1: integer;
    field2: string;
    field3: boolean;
    procedure Clear;
  end;

procedure TSomeRecord.Clear;
begin
  Self := Default(TSomeRecord);
end;

If your compiler doesn't support Default then you can do the same quite simply like this:

procedure TSomeRecord.Clear;
const
  Default: TSomeRecord=();
begin
  Self := Default;
end;

You might prefer to avoid mutating a value type in a method. In which case create a function that returns an empty record value, and use it with the assignment operator:

type
  TSomeRecord = record
    // fields go here
    class function Empty: TSomeRecord; static;
  end;

class function TSomeRecord.Empty: TSomeRecord;
begin
  Result := Default(TSomeRecord);
end;

....

Value := TSomeRecord.Empty;

As an aside, I cannot find any documentation reference for Default(TypeIdentifier). Does anyone know where it can be found?


As for the second part of your question, I see no reason not to continue using records, and allocating them using dynamic arrays. Attempting to manage the lifetime yourself is much more error prone.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...