Советы по Delphi

Динамические массивы III


Вот "демо-модуль", демонстрирующий три различных способа (далеко не все) создания динамических массивов. Все три способа для распределения достаточного количества памяти из кучи используют GetMem, tList используют для добавления элементов в список массива и используют tMemoryStream для того, чтобы распределить достаточно памяти из кучи и иметь к ней доступ, используя поток. Старый добрый GetMem вполне подходит для такой задачи при условии, что массив не слишком велик (<64K).

PS. Я не стал ловить в коде исключения (с помощью блоков Try...Finally}, которые могли бы мне помочь выявить ошибки, связанные с распределением памяти. В реальной системе вы должны быть уверены в своем грациозном владении низкоуровневыми операциями с памятью.

{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}{ Форма, демонстрирующая различные методы создания массива с }{ динамически изменяемым размером. Разместите на форме четыре кнопки,}{ компоненты ListBox и SpinEdit и создайте, как показано ниже, }{ обработчики событий, возникающие при нажатии на кнопки. Button1, }{ Button2 и Button3 демонстрируют вышеуказанных метода. Button4 }{ очищает ListBox для следующего примера. }{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}unit Dynarry1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,Forms, Dialogs, StdCtrls, Spin;
typeTForm1 = 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;
varForm1: TForm1;
implementation
{$R *.DFM}TypepSomeType = ^SomeType;SomeType = Integer;
procedure TForm1.Button1Click(Sender: TObject);TypepDynArray = ^tDynArray;tDynArray = Array[1..1000] Of SomeType;VarDynArray : pDynArray;I : Integer;begin{ Распределяем память }GetMem ( DynArray, SizeOf(SomeType) * SpinEdit1.Value );{ Пишем данные в массив }For I := 1 to SpinEdit1.Value DoDynArray^[I] := I;{ Читаем данные из массива }For I := SpinEdit1.Value DownTo 1 DoListBox1.Items.Add ( 'Элемент ' + IntToStr(DynArray^[I]) );{ Освобождаем память }FreeMem ( DynArray, SizeOf(SomeType) * SpinEdit1.Value );end;
procedure TForm1.Button2Click(Sender: TObject);VarList : tList;Item : pSomeType;I : Integer;begin{ Создаем список }List := tList.Create;{ Пишем данные для списка }For I := 1 to SpinEdit1.Value DoBegin{ Распределяем уникальный экземпляр данных }New ( Item ); Item^ := I;List.Add ( Item );End;{ Читаем данные из списка - базовый индекс списка 0, поэтому вычитаем из I единицу }For I := SpinEdit1.Value DownTo 1 DoListBox1.Items.Add ( 'Элемент ' +IntToStr(pSomeType(List.Items[I-1])^) );{ Освобождаем лист }For I := 1 to SpinEdit1.Value DoDispose ( List.Items[I-1] );List.Free;end;
procedure TForm1.Button3Click(Sender: TObject);VarStream : tMemoryStream;Item : SomeType;I : Integer;begin{ Распределяем память потока }Stream := tMemoryStream.Create;Stream.SetSize ( SpinEdit1.Value );{ Пишем данные в поток }For I := 1 to SpinEdit1.Value Do{ Stream.Write автоматически отслеживает позицию записи,поэтому при записи данных за ней следить не нужно }Stream.Write ( I, SizeOf ( SomeType ) );{ Читаем данные из потока }For I := SpinEdit1.Value DownTo 1 DoBeginStream.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);beginListBox1.Items.Clear;end;
end.

- Robert Wittig [000759]



Содержание раздела