Идёт загрузка страницы...

htp://aptem.net.ru





Delphi 1

Динамические массивы 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;

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 := 1 to SpinEdit1.Value Do
DynArray^[I] := I;
{ Читаем данные из массива }
For I := SpinEdit1.Value DownTo 1 Do
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 := 1 to SpinEdit1.Value Do
Begin
{ Распределяем уникальный экземпляр данных }
New ( Item ); Item^ := I;
List.Add ( Item );
End;
{ Читаем данные из списка - базовый индекс списка 0, поэтому вычитаем из I единицу }
For I := SpinEdit1.Value DownTo 1 Do
ListBox1.Items.Add ( 'Элемент ' +
IntToStr(pSomeType(List.Items[I-1])^) );
{ Освобождаем лист }
For I := 1 to 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 := 1 to SpinEdit1.Value Do
{ Stream.Write автоматически отслеживает позицию записи,
поэтому при записи данных за ней следить не нужно }
Stream.Write ( I, SizeOf ( SomeType ) );
{ Читаем данные из потока }
For I := SpinEdit1.Value DownTo 1 Do
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.

- Robert Wittig [000759]