• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Czego użyć zamiast struct aby sizeof zwracał odpowiednią wartość?

Object Storage Arubacloud
0 głosów
497 wizyt
pytanie zadane 6 czerwca 2023 w C i C++ przez Daaa22 Dyskutant (8,250 p.)
#include <stdio.h>

struct x
{
    int x;
    char c;
};

int main()
{
    printf("%d", sizeof(struct x)); //pokazuje 2*sizeof(int) zamiast sizeof(int)+sizeof(char)

    return 0;
}

Union pokaże sizeof(int), da się jakoś zaalokować pamięć tak żeby nie zabierała niepotrzebnego miejsca?

2 odpowiedzi

+3 głosów
odpowiedź 6 czerwca 2023 przez adrian17 Ekspert (344,860 p.)

Nie, wszystko się zgadza. Rozmiar struktury nie jest równy po prostu sumie rozmiarów elementów, przez konieczność wyrównania:

https://en.cppreference.com/w/c/language/object#Alignment

Ma nawet dokładnie Twój kod jako przykład:

// objects of struct X must be allocated at 4-byte boundaries
// because X.n must be allocated at 4-byte boundaries
// because int's alignment requirement is (usually) 4
struct X {
    int n;  // size: 4, alignment: 4
    char c; // size: 1, alignment: 1
    // three bytes padding
}; // size: 8, alignment: 4

 

+1 głos
odpowiedź 6 czerwca 2023 przez Gynvael Coldwind Nałogowiec (27,530 p.)

Sizeof pokazuje dobrą wartość – po prostu nie bierzesz pod uwagę wyrównania, które jest w struct.

Generalnie każde pole w struct/class będzie miało "naturalne" wyrównanie do adresu podzielnego przez (zazwyczaj) wielkość danego pola. Do tego sam struct też będzie wyrównany jeśli chodzi o wielkość, tak żeby (w razie alokacji tablicy instancji structów) kolejny struct też był na odpowiednio wyrównanym adresie. Więc ten Twój struct ma de facto 3 elementy:

  1. int x (4 bajty)
  2. char c (1 bajt)
  3. + wyrównanie (3 bajty)

Dzięki temu struct ma 8 bajtów, więc jeśli zaalokujesz tablicę dwóch, to pierwsze pole każdego elementu tablicy ma zagwarantowane, że będzie na adresie podzielnym przez 4 (tak jak wymaga tego "naturalne" wyrównanie intów).

Jeśli się zastanawiasz po co te wyrównania, to generalnie chodzi o dostęp do pamięci. Dostęp do elementów na "naturalnie" wyrównanych adresach jest po prostu szybszy (co wynika z tego, że procesor może pominąć pewne checki związane z granicznymi przypadkami co do cache lines / stron pamięci).

W każdym razie jeśli potrzebujesz z jakiegoś powodu struct który ma dokładnie 5 bajtów (np. odczyt/zapis do pliku, albo wysyłka pakietów sieciowych), to rzuć okiem na:

  • #pragma pack
  • __attribute__((packed))

Np.

// zachowanie ustawień i wyłączenie wyrównywania
#pragma pack(push,1)

struct asdf {
  int x;
  char c;
};

// przywrócenie poprzedniego zachowanego ustawienia
#pragma pack(pop)

// sizeof tego structa zwróci 5

 

komentarz 7 czerwca 2023 przez Gynvael Coldwind Nałogowiec (27,530 p.)

ETA: ↑↑↑ wcześniej tu był jeszcze jeden komentarz, serio!1one

Akurat liczbę oddzielnych dostępów do pamięci da się bardzo łatwo przewidzieć widząc sam adres i znając wielkość zmiennej + rozumiejąc model pamięci. Np. rozważania dla inta na x86:

  • 0x1004 - jeden dostęp do pamięci.
  • 0x1005 - dwa dostępy do pamięci w obrębie tego samego cache line (2x wolniejsze).
  • 0x103f - dwa dostępy do pamięci na dwóch różnych cache line (potencjalnie sporo wolniejsze).
  • 0x1fff - dwa dostępy do pamięci na dwóch różnych stronach pamięci (dużo dużo wolniejsze).

Dla zainteresowanych sekcja 4 w tym papierku :)
https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/42189.pdf

Podobne pytania

–1 głos
0 odpowiedzi 458 wizyt
pytanie zadane 9 czerwca 2018 w C i C++ przez MsMaciek123 Pasjonat (24,760 p.)
0 głosów
1 odpowiedź 292 wizyt
pytanie zadane 19 kwietnia 2023 w C i C++ przez Daaa22 Dyskutant (8,250 p.)
0 głosów
1 odpowiedź 670 wizyt

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...