Delphi World - Динамические массивы 3
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Динамические массивы 3

Автор: Robert Wittig

Вот "демо-модуль", демонстрирующий три различных способа (далеко не все) создания динамических массивов. Все три способа для распределения достаточного количества памяти из кучи используют 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.

Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования