Code
W kolejności chronologicznej.
Podseria | Odcinek | Opis |
---|---|---|
Rand | #1: rand() i przedział | - |
Rand | #2: rand() i zwiększenie przedziału i liczby float | - |
Linked list | #3: linked list: dodawanie, przechodzenie | - |
Linked list | #4: linked list: usuwanie elementu | - |
Linked list | #5: linked list: API, iteratory | - |
Linked list | #6: linked list: API, zrzut do tablicy | - |
Linked list | #7: linked list: API, callback | - |
Rand | #8: rand, rozkład wyników | - |
Pointery | Pointery #1 | - |
Pointery | Pointery #2 | - |
Pointery | Pointery #3 | - |
Pointery | Pointery #4 | - |
Pointery | Pointery #5 | - |
Pointery | Pointery #6 | - |
Pointery | Pointery #7 | - |
Pointery | Pointery #8 | - |
Pointery | Pointery #9 | - |
DLL | #1 Podstawy DLL | Godzinny odcinek omawiający podstawy DLL. |
DLL | #2 Pluginy (part 1/2) | - |
DLL | #2 Pluginy (part 2/2) | - |
Podstawy | Konfiguracja środowiska | Podstawowa konfiguracja środowiska: MinGW + ustawienie ścieżek w PATH + trochę o Total Commanderze. |
Materiały dodatkowe
Zachęcam również do rzucenia okiem na odcinek o Maszynach Wirtualnych z serii FAQ.
Comments:
int main()
{
struct x_st{
char p;
int z;
short k;
};
printf("%d", sizeof(struct x_st));
return 0;
}
wypisuje mi ze ma 12 bajtow, a jak zamienie kolejnosc w strukturze (int na poczatku albo na koncu ) to daje 8 bajtow.
Z czego to wynika?
W skrócie i uproszczeniu: pola w strukturze są alignowane do naturalnych adresów (czyli dla int'a to będą adresy podzielne przez 4, dla shorta przez 2, a dla char'a jakiekolwiek);
Tak więc w przypadku który przedstawiłeś między "p" a "z" będą 3 bajty przerwy (paddingu), ponieważ adres int'a musi być podzielny przez 4. Kolejny short "k" ma co prawda dwa bajty, ale z uwagi na to, że w potencjalnej tablicy instancji takich struktur w każdym elemencie musi być adres "z" wyrównany do 4rech, to wielkość struktury będzie wyrównana do najbliższego iloczynu 4 (czyli de facto dwa bajty paddingu będą za "k" wrzucne).
Gdyby zmienić to na: char p; short k; int z;, to całość będzie miała tylko 8 bajtów, ponieważ short "k" zmieści się w tą trzybajtową przerwę która była między "p" a "z" w poprzednim przypadku.
(z punktu widzenia bezpieczeństwa trzeba pamiętać, że w tym "paddingach" mogą być pozostałości innych danych z pamięci, wiec przy wysyłaniu/zapisywaniu do pliku najlepiej te paddingi wyczyścić - pisałem coś o tym więcej w artykule "Diabeł tkwi w szczegółach: C/C++ cz.2", bodajże w numerze z października 2012 magazynu Programista)
A btw, to wyrównywanie można wyłączyć per-struktura - przydatne jeśli się operuje na niewyrównanych strukturach w plikach/pakietach sieciowych.
Można to osiągnąć (w zależności od kompilatora) używając:
#pragma pack(push, 1)
tutaj definicja struktury
#pragma pack(pop)
Albo korzystając z __attribute__((packed)) dla całej struktury lub danego pola (można łatwo znaleźć przykłady na google)
To program z odcinka o multithreadingu
problem polega na tym, że wyniki są identyczne gdy zmienna x jest poprzedzona slowem kluczowym
__thread jak i gdy tego slowa nie ma i jest to zwykla zmienna globalna.
Watki w obu przypadka NIE nadpisuja sobie jej wartosci:
przykladowy wynik:
1 (13939)
2 (6064)
1 (13939)
2 (6064)
Jak to wyjasnic?
Wyjaśnienie jest dość proste - wypisujesz parametr "param", a nie zmienną "x" ;)
Zmienne 'x' się zmienia oczywiście:
DWORD __stdcall MyProc(void *param)
{
x = (int)param;
std::cout<<x<<" ("<<GetCurrentThreadId()<<")\n";
Sleep(1000);
std::cout<<x<<" ("<<GetCurrentThreadId()<<")\n";
return 0;
}
Start
1 (8500)
2 (15516)
2 (8500)
2 (15516)
Stop
Cheers,
Add a comment: