Вот "демо-модуль", демонстрирующий три различных способа (далеко не все) создания динамических массивов. Все три способа для распределения достаточного количества памяти из кучи используют GetMem, tList используют для добавления элементов в список массива и используют tMemoryStream для того, чтобы распределить достаточно памяти из кучи и иметь к ней доступ, используя поток. Старый добрый GetMem вполне подходит для такой задачи при условии, что массив не слишком велик (<64K).
PS. Я не стал ловить в коде исключения (с помощью блоков Try...Finally}, которые могли бы мне помочь выявить ошибки, связанные с распределением памяти. В реальной системе вы должны быть уверены в своем грациозном владении низкоуровневыми операциями с памятью.
Code: |
{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} { Форма, демонстрирующая различные методы создания массива с } { динамически изменяемым размером. Разместите на форме четыре кнопки,} { компоненты ListBox и SpinEdit и создайте, как показано ниже, } { обработчики событий, возникающие при нажатии на кнопки. Button1, } { Button2 и Button3 демонстрируют вышеуказанных метода. Button4 } { очищает ListBox для следующего примера. } {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} unit Dynarry1;
interface
uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Spin;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; SpinEdit1: TSpinEdit; ListBox1: TListBox; Button4: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.DFM} type pSomeType = ^SomeType; SomeType = Integer;
procedure TForm1.Button1Click(Sender: TObject); type pDynArray = ^tDynArray; tDynArray = array[1..1000] of SomeType; var DynArray: pDynArray; I: Integer; begin { Распределяем память } GetMem(DynArray, SizeOf(SomeType) * SpinEdit1.Value); { Пишем данные в массив } for I := 1to SpinEdit1.Value do DynArray^[I] := I; { Читаем данные из массива } for I := SpinEdit1.Value downto1do ListBox1.Items.Add('Элемент ' + IntToStr(DynArray^[I])); { Освобождаем память } FreeMem(DynArray, SizeOf(SomeType) * SpinEdit1.Value); end;
procedure TForm1.Button2Click(Sender: TObject); var List: tList; Item: pSomeType; I: Integer; begin { Создаем список } List := tList.Create; { Пишем данные для списка } for I := 1to SpinEdit1.Value do begin { Распределяем уникальный экземпляр данных } New(Item); Item^ := I; List.Add(Item); end; { Читаем данные из списка - базовый индекс списка 0, поэтому вычитаем из I единицу } for I := SpinEdit1.Value downto1do ListBox1.Items.Add('Элемент ' + IntToStr(pSomeType(List.Items[I - 1])^)); { Освобождаем лист } for I := 1to SpinEdit1.Value do Dispose(List.Items[I - 1]); List.Free; end;
procedure TForm1.Button3Click(Sender: TObject); var Stream: tMemoryStream; Item: SomeType; I: Integer; begin { Распределяем память потока } Stream := tMemoryStream.Create; Stream.SetSize(SpinEdit1.Value); { Пишем данные в поток } for I := 1to SpinEdit1.Value do { Stream.Write автоматически отслеживает позицию записи, поэтому при записи данных за ней следить не нужно } Stream.Write(I, SizeOf(SomeType)); { Читаем данные из потока } for I := SpinEdit1.Value downto1do begin Stream.Seek((I - 1) * SizeOf(SomeType), 0); Stream.Read(Item, SizeOf(SomeType)); ListBox1.Items.Add('Элемент ' + IntToStr(Item)); end; { Освобождаем поток } Stream.Free; end;
procedure TForm1.Button4Click(Sender: TObject); begin ListBox1.Items.Clear; end;
end. |
Взято из Советов по Delphi от Валентина Озерова
Сборник Kuliba
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!