Packed

Szczawik

Packed - definicja rodzaju rekordu.

Jeśli w kodzie programu zostanie zdefiniowany rekord, w którym elementy mają różny rozmiar, kompilator może w taki sposób zwiększyć pamięć zajmowaną przez pole określonego typu, aby była ona wielokrotnością największego z typów lub wielokrotnością wartości zdefinowanej w opcjach kompilatora:

Delphi 7/Menu główne/Project/Options/Compiler/Code generation/Record field alignment

Dzięki temu, bez względu na rozmiar konkretnego pola, początkowy obszar pamięci zajmowanej przez kolejne pole znajduje się zawsze o wielokrotność ustalonej liczby bajtów dalej, co pozwala na szybszy dostęp do kolejnych pól w rekordach.

Rozwiązanie takie ma jednak wadę - rekord nie zajmuje tylu bajtów w pamięci, ile wynikałoby z sumy rozmiarów kolejnych pól. Zajmuje obszar równy sumie bajtów pól, zwiększony o pamięć potrzebną do poszerzenia rozmiaru kolejnych pól do przyjętego rozmiaru wyrównania. Może to być utrudnieniem na przykład przy wczytywaniu danych z plików amorficznych do rekordów.

Jeśli jednak w definicji rekordu pojawi się słowo packed, rekord nie zostanie zoptymalizowany, jednak dzięki temu będzie miał dokładnie taki rozmiar, jaki wynika bezpośrednio z rozmiaru pól.

Poniższy kod prezentuje różnicę między definicją rekordu z użyciem i bez użycia słowa kluczowego packed. Warto zwrócić uwagę, że rekord bez słowa kluczowego packed zajmuje 4 bajty, mimo, że pola typów Byte i Word zajmują w sumie 3 bajty. Wyrównanie pola typu Byte zajęło 1 dodatkowy bajt pamięci, jednak dzięki temu, przesunięcie między kolejnymi początkami pól wynosi 2 bajty.

program Przyklad;
 
{$APPTYPE CONSOLE}
 
type
  //rekord bez wyrównania
  r1 = packed record
    a:byte;
    b:word;
  end;
 
  //rekord z wyrównaniem
  r2 = record
    a:byte;
    b:word;
  end;
 
Begin
  WriteLn('Rozmiar r1=', sizeof(r1)); //Rozmiar r1=3
  WriteLn('Rozmiar r2=', sizeof(r2)); //Rozmiar r2=4
End.

0 komentarzy