views:

1281

answers:

2

Hi everybody. I'm developing class to represent special kind of matrix:

type
  DifRecord = record
    Field: String;
    Number: Byte;
    Value: smallint;
  end;

type
  TData = array of array of MainModule.DataRecord;

type
  TDifference = array of DifRecord;

type
  TFogelMatrix = class
  private
    M: Byte;
    N: Byte;
    Data: ^TData;
    DifVector: ^TDifference;
    procedure init(); 
  public
    constructor Create(Rows, Cols: Byte);
    destructor Destroy;
  end;

Now in constructor I need to reserve memory for Data and DifVector class members. I use pointers to array of records, as you see. So, the main question is, how can I correctly reserve memory? I suppose I can not use something like that:
new(Data);
new(DifVector);
cause I`m loosing the main idea - to reserve memory space, as much as I want to, at run-time. Thanks for comments.

+8  A: 

Since you're using dynamic arrays, array of, then you should use SetLength to specify the length of the array, which can be done dynamically.

ie. like this:

SetLength(Data, 100);

This will not reserve 100 bytes, but will reserve enough space to hold 100 elements of whatever type the array holds.

Change your declarations for the arrays to simple arrays:

Data: TData;
DifVector: TDifference;

and use it with SetLength, it should do the trick.

Lasse V. Karlsen
and what about Data? It`s a matrix so I need to use 2 parameters?<code> SetLength(Data, M, N)?</code>
chester89
Yes, that should work.
Lasse V. Karlsen
+1  A: 

Also note that In Delphi variables of a dynamic array type are stored as a pointer (in DotNet-speak you would call this a reference-type).

Unless you cast this variable to a pointer, the compiler won't let you do the allocation yourself. You should use SetLength() like lassevk mentioned already.

With a multi-dimensional array (like TData), you could set both dimensions in one go, by setting all dimension with one call to SetLength(). This results in a cube-like structure (each dimension has equal length). But it's also possible to give each index within a dimension a different length to it's next dimension. With two dimensions, this is sometimes called a 'jagged' array.

To do this, you would write it out like this :

SetLength(Data, SizeOfFirstDimension);
for i = 0 to SizeOfFirstDimension - 1 do
  SetLength(Data[i], SizeOfSecondDimensionPerIndex(i));

In this example, I use a function called 'SizeOfSecondDimensionPerIndex' to determine the size of each array in the 2nd dimension, but you could determine this size any way you want.

On a side-note, I would advise you to use the 'R'-prefix for record-type definitions. I know this not in any of the major coding-style guides, but if you look at 'P'-prefixes for pointers, 'I'-prefixes for interfaces, 'F'-prefixes for class-fields, 'a'-prefixes for arguments, 'C'-prefixes for constants, 'S'-prefixes for resourcestring's, you can follow this logic and use an 'R'-prefix for records. I know this has helped me to get a better grasp of my code!

Good luck!

PatrickvL