Как я могу зарезервировать память для указателя на массив в Delphi? - PullRequest
1 голос
/ 28 ноября 2008

Я разрабатываю класс для представления особого вида матрицы:

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;

Теперь в конструкторе мне нужно зарезервировать память для членов класса Data и DifVector. Как вы видите, я использую указатели для массива записей. Итак, главный вопрос: как правильно зарезервировать память? Я полагаю, я не могу использовать что-то подобное:
new(Data);<br> new(DifVector);<br> потому что я теряю основную идею - зарезервировать пространство памяти, сколько я хочу, во время выполнения. Спасибо за комментарии.

Ответы [ 2 ]

10 голосов
/ 28 ноября 2008

Поскольку вы используете динамические массивы, array of, вам следует использовать SetLength, чтобы указать длину массива, что можно сделать динамически.

есть. как это:

SetLength(Data, 100);

Это не зарезервирует 100 байтов, но зарезервирует достаточно места для хранения 100 элементов любого типа, который содержит массив.

Измените ваши объявления для массивов на простые:

Data: TData;
DifVector: TDifference;

и используйте его с SetLength, это должно сработать.

1 голос
/ 28 ноября 2008

Также обратите внимание, что в Delphi переменные динамического типа массива хранятся в виде указателя (в DotNet-говорящем вы бы назвали это ссылочным типом).

Если вы не приведете эту переменную к указателю, компилятор не позволит вам выполнить выделение самостоятельно. Вы должны использовать SetLength (), как уже упоминалось lassevk.

Используя многомерный массив (например, TData), вы можете установить оба измерения за один раз, установив все измерения одним вызовом SetLength (). В результате получается кубоподобная структура (каждое измерение имеет одинаковую длину). Но также возможно дать каждому индексу в измерении длину, отличную от его следующего измерения. В двух измерениях это иногда называют «зубчатым» массивом.

Для этого вы должны написать это так:

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

В этом примере я использую функцию с именем SizeOfSecondDimensionPerIndex, чтобы определить размер каждого массива во 2-м измерении, но вы можете определить этот размер любым удобным вам способом.

В дополнение к этому, я бы посоветовал вам использовать префикс 'R' для определений типа записи. Я знаю это не во всех основных руководствах по стилю кодирования, но если вы посмотрите на 'P' -приставки для указателей, 'I'-префиксы для интерфейсов,' F'-префиксы для полей классов, 'a'-префиксы для аргументов, C-префиксы для констант, S-префиксы для строк ресурсов, вы можете следовать этой логике и использовать R-префикс для записей. Я знаю, что это помогло мне лучше понять мой код!

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...