Календарь на Май 2024 года: calendar2008.ru/2024/may/
Навигация
Главная »  Delphi 

Изменение размеров массивов


Источник: codingrus
Kest
Delphi до версии 4.0 (Хотя, начиная с четвертой версии, Delphi поддерживает динамические массивы, вставка и удале-
ние элементов в середине такого массива иногда выполняется довольно долго, так как приходиться
переносить множество элементов, чтобы занять появившуюся пустую ячейку. Использование указа-
телей зачастую решает проблему низкой скорости алгоритма.) не позволяет изменять размеры массивов. После объяв-
ления размер массива остается постоянным. Однако с помощью указателей мож-
но создавать массивы с изменяемым размером - динамические массивы.
Сначала с помощью инструкции type следует определить тип массива с мак-
симальным размером. Чтобы индексы массива начинались с единицы, нужно уста-
новить его размер от 1 до 1 000 000, затем определить тип, который является указа-
телем на этот массив.
Для выделения памяти под массив используйте функцию GetMem. Ее второй
параметр указывает размер массива в байтах. Это значение должно быть равно
числу элементов массива, умноженному на размер каждого элемента. Определить
размер каждого элемента можно при помощи функции SizeOf.
Для освобождения памяти, выделенной под массив, необходимо использовать
процедуру FreeMem.
Программа SizeArr может служить примером изменения размеров массива. Вве-
дите количество элементов массива и нажмите кнопку Resize (Изменить размер).
Программа изменит размер массива. В следующем фрагменте кода представлены
наиболее интересные части программы.
type
// Определение типа массива.
.TIntArray = array [1.. 1000000] of Integer;
// Определение указателя на тип массив.
Pint Array = ATInt Array;
// <часть кода пропущена>. . .
// Изменение размера массива.
procedure TSizeArrForm.CmdResizeClick(Sender : TObject) ;
var
Numltems : Integer; // Количество элементов массива.
Items : PIntArray; // Массив элементов.
I : Integer;
Txt : String;
begin
// Выделение памяти для массива.
Txt : =
Numltems := StrToInt (NumltemsText .Text) ;
GetMem(Items,NumItems*SizeOf (Integer) ) ;
// Заполнение массива значениями.
for i : = 1 to Numltems do
begin
Txt := txt+IntToStr(ItemsA[i] ) + ' ' ;
end;
ItemsLabel. Caption := txt;
// Освобождение массива.
FreeMemf Items) ;
end;



Изменение размеров массива - мощная, но несколько опасная методика. Ра-
ботая с массивом, Delphi не определяет его размер. В программе SizeArr Delphi
воспринимает массив как указатель, содержащий миллион ячеек. Если программа
фактически выделила память только для 10 элементов, Delphi не определит по-
пытку доступа к 1 00-му элементу как ошибку. Вместо того чтобы выдать при компи-
ляции сообщение о том, что индекс массива вышел за пределы, во время выполне-
ния программа будет пытаться сделать запись в 100-ю позицию массива. В лучшем
случае обращение к этой ячейке памяти просто остановит работу программы. В худ-
шем это вызовет неявный сбой, который будет очень сложно найти.
Подобная проблема возникает, если программа использует неверно заданную
нижнюю границу массива. Предположим, что тип массива определен так, как опи-
сано в следующем фрагменте кода:
TIntArray = array [1.. 1000000] of Integer;


Подобную ошибку допустить очень просто. Неприятности начнутся, когда
программа попробует обратиться к элементу массива в нулевой позиции.
При объявлении в процедуре нового массива, такого как PIntArray, его гра-
ницы не указываются. Необходимо помнить, какой тип массива вы определили да-
лее в программе.
Программа освобождает выделенную для обычного массива память, когда он
выходит из области видимости. Например, массив, объявленный в пределах про-
цедуры, автоматически освобождается, когда процедура заканчивается.
С другой стороны, память, выделенная с помощью процедуры GetMem, остает-
ся таковой до тех пор, пока не освободится с помощью процедуры FreeMem. Пока
программа не будет завершена, доступа к памяти не будет. При этом неоднократ-
ный вызов процедуры занимает много системной памяти.
Наконец, существенную проблему создает обращение к памяти, освобожден-
ной процедурой FreeMem. Если программа освобождает память массива и затем
обращается к этому массиву, то следствием может быть либо ее остановка, либо
неявный сбой. Можно сократить вероятность возникновения такого эффекта,
сбрасывая указатель массива на нуль после освобождения памяти. В этом случае
вместо неявного сбоя попытка обращения к массиву вызовет ошибку нарушения
доступа.
Несмотря на подстерегающие опасности изменение размеров массива - очень
мощная методика. При работе со списками, меняющими свой размер, она позволя-
ет достигать очень высокой производительности.
Delphi, начиная с версии 4.0, поддерживает встроенный механизм изменяемых
массивов. По своему синтаксису работа со встроенными динамическими массива-
ми очень похожа на работу с обычными массивами языка Pascal.
Сначала следует объявить переменную массива, не указывая при этом его гра-
ниц. Изменение его размера производится с помощью процедуры SetLength. Так
как заранее длина массива не известна, потребуются еще три функции: Length,
возвращающая количество элементов массива, Low, возвращающая индекс перво-
го элемента (обычно 0) и High, возвращающая индекс последнего элемента.
// Изменение размера массива.
procedure TSizeArrForm.CmdResizeClick(Sender : TObject);
var
Numltems : Integer; // Количество элементов массива.
Items : Array Of Integer; // Массив элементов.
I : Integer;
Txt : String;
begin
// Инициализация массива.
NumIt ems : = S t rToInt(NumIt emsText.Text);
SetLength(Items,Numltems);
// Заполнение массива значениями.
Txt : =
for i := Low(Items) to High(Items) do
begin
Items[i] := i;
Txt := txt + IntToStr(Items[i]) + '' ;
end;
1 ItemsLabel.Caption := Txt;
// Освобождение массива.
SetLength(Items,0);
end;


 

 Rational Software Delivery Platform Team Products Release 7.
 Рекомендации по подготовке к экзаменам Borland.
 Вызов Delphi DLL из MS Visual C++ (исходники).
 Создание WEB-приложений в среде Delphi (исходники).
 Crypt - Delphi программа для шифрования (исходники).


Главная »  Delphi 

© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено.