1

In an array of type TArrayParams that stores records of type TParams, according to the code below, there is a string field that can vary from 1 to 1000. How to check the length (in bytes) of memory that TArrayParams will have?

  TParams = record
     S: String; // Length may vary
     I: Integer;
  end;
  TArrayParams = TArray<TParams>;

var arr: TArrayParams;
    i: Integer;
begin
     SetLength(arr, 2);

     for i := 0 to 1 do
     begin
        arr[i].S := 'my random string.... xyz up to (maybe) 1000';
        arr[i].I   := i;
     end;

     // What is the length (in bytes) of the "arr" array's memory space?
     SizeOf(arr) ??? It Doesn't work...
     Length(arr) ??? It Doesn't work...
     ByteLength(arr) ?? It Doesn't work...
end;
21
  • You'll have to iterate and total up each record manually. Commented Jul 24, 2019 at 13:12
  • That's what I feared I had to do ... Commented Jul 24, 2019 at 13:14
  • 1
    @wBB A TParams will always be 8 bytes long (in 32 bits exe). A string is a pointer, so it's always 4 bytes. Commented Jul 24, 2019 at 13:50
  • 1
    Leaving that aside, can you explain why you want to know the size of anything? If you want to write to a stream, don't you just write to a stream? Why does your code need to know the size of anything? Commented Jul 24, 2019 at 14:03
  • 1
    You can't just blit it to a stream, because the data is not held contiguously. How you save the data depends on your needs. Sometimes a binary approach is good, sometimes you'd be better with XML or JSON. It all depends. You've got quite a few knowledge gaps that need to be plugged before you start coding this for real. Commented Jul 24, 2019 at 14:23

1 Answer 1

1

In the comments you were already told that strings are not stored in the records, so you can't simply use stream.write(record, SizeOf(Record)) to save such a record because that would only write a pointer to the stream that is not valid outside the context of your program. So, you need some other way of storing the data. One option would be text: Since the record only contains a number and a string, you could simply write them as text:

var
  sl: tstringlist;
begin
  sl := tstringlist.create;
  try
    for i := Low(arr) to High(arr) do begin
       sl.Add(Format('%d'#9'%s', [arr[i].I, arr[i].s]));
    end;
    sl.SaveToFile('c:\path\to\filename.txt');
  finally
    sl.Free;
  end;
end;

Please note that this code is completely untested!

The resulting file could be loaded into a text editor or e.g. OpenOffice Calc for display purposes.

If text (actually csv with tab as column separator) is not what you want, you need to be more specific in your question.

Sign up to request clarification or add additional context in comments.

3 Comments

This doesn't answer the question that was asked
It answers what I understood from the comments, what the actual problem is. I might of course be wrong.
Indeed, but this site is a little pedantic about answering the actual question. If you feel you want to answer the question asked in the comments, you should edit the question accordingly, to match what was stated in the comments. That's just how SO works.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.