Опаковка за сложни типове данни в Делфи

В тази статия бих искал да кажа и да се покаже особеностите на употребата
"Запечатайте сложни типове данни" в Делфи.

Всички някога трябваше да се справят с документацията. Записът е използван в много случаи,
- да се създаде директориите на файла, лесно групиране и представяне
данни, програмиране система и т.н. Например, при отваряне на файла Windows.pas
(Стандартен модул се свързва към раздела за приложения), можете да намерите нещо подобно
такова описание:

_POINTL = опаковани запис
х: Longint;
Y: Longint;
приключи;

TISHMisc = опаковани рекорд
При число // Той се използва с възможности за навлизане
0: (PhysicalAddress: DWORD);
1: (VirtualSize: DWORD);
приключи;

Какво тук се употребява за пакетирани ключова дума? Опакован дума казва Delphi
свеждане до минимум на паметта. Така се оказва, без тази дума в нашата структура
Това отнема повече памет?

Ето един примерен запис:

TRecord = Запис
pole1. байт;
pole2. низ [4];
pole3. цяло число;
pole4. int64;
приключи;

Да се ​​изчисли размера: pole1 - 1 байт, pole2 - 5 байта (надявам се не
забравили 4 байта и размер на код съгласно 1), pole3 - 4 байта, pole4 - 8 байта.
Ако ги добавите получите 18 байта. Нека да проверим:

size1: = sizeof (TRecord);
ShowMessage ( "нормален размер запис = '+ IntToStr (size1));

Изненадани ли сте? Сега добавете думата опаковани преди дума ... с размера на записа 18 като
оценява по-рано. Така че, когато сме липсва, цялата 6 байта. И ако имаме
масив от 10 милиона такива записи, например в някоя директория, ние
Ние губят около 57 мегабайта?

Нека да видим защо това е така. За това, аз използвах вградената
Disassembler в Делфи. Формата на бутон хвърлей и кликване манипулатор напишете:

процедура TForm1.Button1Click (Sender: TObject);
тип
// нормален запис
TRecord = Запис
pole1. байт;
pole2. низ [4];
pole3. цяло число;
pole4. int64;
приключи;
// опаковани запис
TPackedRecord = Опакован рекорд
pole1. байт;
pole2. низ [4];
pole3. цяло число;
pole4. int64;
приключи;

Не забравяйте, че ние pole1 присвояване на стойност до $ FF (т.е. = 255), pole2 = 'хакне', pole3
= $ AAAAAAAA (4 байта, т.е. = 2863311530) и т.н. Вижте снимката, аз съм на него
Аз показва структурата на байт и как те се намират в паметта.

Сега провери опаковани записа. Rec променлива в кода, за да замени
packedRec, т.е. Ние използваме най-пълен запис. И ние правим всичко едно и също нещо:

Тук можем да видим, че не байт изравняване не е, и всички данни (област)
Те подредени един зад друг - опаковани.

Може би въпросът: защо данните в първия пример, се изравни с
8-байт граница? Всички въпроса в опциите на компилатора. Ако отворите на проекта -
Опция - Compiler (опции на компилатора), а след това ще има малко по списък Запис на терен
схема, в която може да избере желания подравняване (8,4,2 или 1 байт). не
Забравяме за пренареждане на проекта след промяната. По начина, по привеждане в съответствие на 1 байт
и има пакет с данни.

Вторият въпрос е защо не винаги се опаковат данни? За съжаление, на опаковката
Информация има не само предимства, но и недостатъци. Така например, за изравняване на границата
увеличим времето за достъп до полетата. Поради това е необходимо да се използва пакет мъдро.

Между другото, в една и съща Windows.pas файл може да се намери не само опаковане записи, но
и масиви, ето един пример:

CprMask: опаковани масив [0..3] на DWORD;

Опитайте сами да анализират опаковката на масива.

Покажете тази статия на приятел: