Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

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

Delphi , Синтаксис , Массивы

Динамические массивы 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. Каждый метод использует функцию GetMem для выделения памяти из кучи и затем манипулирует массивом с помощью различных техник.

Вот разбивка каждого события клика кнопки:

  1. Button1Click: Этот метод создает массив из 1000 элементов типа SomeType, который определен как целое число. Массив выделяется с помощью GetMem, и его размер определяется значением в контроле SpinEdit. Затем массив заполняется значениями от 1 до указанного размера, и содержимое отображается в списке.

  2. Button2Click: Этот метод создает динамический список (связанный список) с помощью класса tList. Он выделяет память для каждого элемента с помощью функции New, заполняет список значениями от 1 до указанного размера и затем отображает содержимое в списке. Когда закончено, он освобождает каждый элемент с помощью Dispose и наконец освобождает список сам с помощью Free.

  3. Button3Click: Этот метод использует поток памяти (tMemoryStream) для создания динамического массива. Он выделяет пространство для массива, установив размер потока, записывает значения в поток с помощью Write и затем читает обратно значения с помощью Read. Содержимое отображается в списке.

  4. Button4Click: Этот метод просто очищает содержимое списка, что полезно для сброса отображения перед созданием нового динамического массива.

Код демонстрирует три различных подхода к управлению памятью:

  • Использование GetMem для выделения фиксированного блока памяти (Button1)
  • Использование New и Dispose для управления отдельными объектами в связанном списке (Button2)
  • Использование потока памяти (tMemoryStream) для динамического выделения и управления памятью (Button3)

В целом, рекомендуется использовать подход, который лучше всего подходит к вашим конкретным требованиям. Например, если вам нужно создать массив с фиксированным размером, использование GetMem может быть более эффективно. Если вам нужно создать динамический список, использование tList или другого реализации связанного списка может быть более подходящим.

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

Данная статья демонстрирует три различных метода создания динамических массивов на языке Delphi, используя GetMem, tList и tMemoryStream соответственно.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Массивы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-02 00:53:43/0.003619909286499/0