Thursday, October 09, 2008

Delphi 2009: SizeOf and Length

SizeOf and Length always confuse me.  Some time both function return same result but not always.  There are situations they have same behaviors but not always.

In Delphi 2009 documentation:

SizeOf

function SizeOf(X): Integer;

Returns the number of bytes occupied by a variable or type.

Length

function Length(S): Integer;

Returns the number of characters in a string or elements in an array.

Case 1: Apply on Static Array

For static array, the size of array is statically reserved by compiler.  Thus, SizeOf know the total number of bytes allocated for the array. 

Length will always behave as defined regardless of the element size of array, that is return the number of element in the array.

var A: array[0..9] of byte;

  • SizeOf(A) return 10
  • Length(A) return 10

var B: array[0..9] of char;

  • SizeOf(B) return 20 (in Delphi 2009, char is WideChar of 2 bytes in size)
  • Length(B) return 10

Case 2: Apply on Dynamic Array

Unlike static array, a variable reference dynamic array is of pointer type.  Thus, apply SizeOf on a dynamic array point always return 4, that is same as SizeOf(Pointer) no matter how much memory allocated to the dynamic array at runtime.

Length as always, return the number of elements in array.

var A: array of byte;  // or TBytes
begin
  SetLength(A, 10);
end;

  • SizeOf(A) return 4
  • Length(A) return 10

var C: array of char;  // or TBytes
begin
  SetLength(C, 10);
end;

  • SizeOf(C) return 4
  • Length(C) return 10
  • To get the total number of bytes allocated for a dynamic array, use Length(C) * SizeOf(Char) and it return 20.

Case 3: Apply on Open Array

Open array parameters allow arrays of different sizes to be passed to the same procedure or function. To define a routine with an open array parameter, use the syntax array of type (rather than array[X..Y] of type) in the parameter declaration. For example,

procedure MyProc(A: array of integer);
begin
  WriteLn('SizeOf(A)=', SizeOf(A));

  WriteLn('Length(A)=', Length(A));
end;

declares a procedure called MyProc that takes a integer array of any size.

We may pass either a static or dynamic array to MyProc but not limited to that.

Example 1: Dynamic array

var A: array of integer;
begin
  SetLength(A, 10);
  MyProc(A);
end;

The output is

  • SizeOf(A)=40
  • Length(A)=10

Example 2: Static array

var A: array[0..9] of integer;
begin
  MyProc(A);
end;

The output is

  • SizeOf(A)=40
  • Length(A)=10

Example 3: Static array

begin
  MyProc([0,1,2,3,4,5,6,7,8,9]);
end;

The output is

  • SizeOf(A)=40
  • Length(A)=10

Example 4: Integer variable

Instead of an array, you can pass a variable of the open array parameter's base type. It will be treated as an array of length 1.

var i: integer;
begin
  MyProc(i);
end;

The output is

  • SizeOf(A)=4
  • Length(A)=1

Example 5: Open Array or Dynamic Array

It is easy to confuse about the array syntax.  The syntax of open array parameters resembles that of dynamic array types, but they do not mean the same thing.  If you declare a type identifier for an array, it will be treated as dynamic array:

type
  TIntegerArray = array of integer;

procedure MyProc(A: TIntegerArray);
begin
  WriteLn('SizeOf(A)=', SizeOf(A));
  WriteLn('Length(A)=', Length(A));
end;

var A: TIntegerArray;
begin
  SetLength(A, 10);
  MyProc(A);
end;

The output is

  • SizeOf(A)=4
  • Length(A)=10

Reference:

  1. Open array parameters and array of const

1 comment:

Renyi said...

Delphi 2009 strings are fully unicode.

Strings now are 2bytes per char.

http://www.jacobthurman.com/?p=29

Google is your friend ...