2016-07-26 12 views

Odpowiedz

12

Istnieje kilka faktów o wyrównanie w strukturach, które warto wspomnieć:

  1. Wielkość typu jest zawsze wielokrotnością jej wyrównanie.
  2. Dopasowanie struktury jest zawsze wielokrotnością wyrównania wszystkich jej elementów.

Tak więc, ponieważ jeden z tych elementów ma wyrównanie 4096, wyrównanie samej struktury wynosi co najmniej 4096. Najprawdopodobniej będzie to dokładnie takie.

Ale ponieważ potrzebuje dopełnienia 4080 bajtów przed c, rozmiar struktury wynosi co najmniej 4104, ale musi to być wielokrotność 4096, czyli wyrównanie. Tak więc wzrasta do 8192.

4

To dlatego, że sizeof mówi, gdzie zostanie umieszczony następny element tablicy. To znaczy, jeśli masz deklaracji

struct A a[2]; 

Będziesz potrzebować zarówno a[0].c i a[1].c być wyrównane 4096 bajtów.

Ściśle mówiąc kompilator mógł zarządzać tego dokonać o rozmiarze 4096, ale nie prawdopodobnie dlatego struct A posiądą wymaganie wyrównania i umieścić dwa int s przed polem .c który też musi być wyrównane, który wstawia 4080 ish bajtów wypełnienia między .b i .c, a następnie 4080 ish bajtów wypełnienia po .d.

Sposób, w jaki wykonał to kompilator (bez zmiany układu elementów struktury), ma na celu rozszerzenie koncepcji wyrównania. Zamiast tylko wymagań, że adres musi upaść na adres formularza N*4096, może rozszerzyć to z przesunięciem wymagającym, aby spadł na adres z formularza N*4096-2*sizeof(int). Podanie struct A takiego wymogu spowodowałoby, że element .c stałby się naturalnie 4096 wyrównany bajtami bez konieczności wypełniania między .b i .c (też).

+3

Kompilator * nie * umożliwia zmianę układu elementów konstrukcyjnych zgodnie z oczekiwaniami. Standard C wymaga, aby wskaźnik do 'a' był także wskaźnikiem do otaczającego obiektu, więc poniższe jest legalne:' int * ptr = &t.a; ((struct A *) ptr) -> b = 42; "Jako takie, kompilator * nie może * zdołać spakować danej struktury w ciągu 4096 bajtów. – cmaster

+0

@cmaster Zmiana kolejności elementów nie jest jedynym sposobem, aby działało z rozmiarem '4096' bajtów. Kompilator może również wymagać, aby 'struct A' musiał mieć adres' 2 * sizeof (int) 'przed granicą' 4096' bajtów. – skyking

Powiązane problemy