Powrót do spisu serii

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.

Powrót do spisu serii

Comments:

2013-03-21 15:11:14 = bar
{
#include <stdio.h>
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?
}
2013-03-21 22:18:04 = Gynvael Coldwind
{
@bar
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)

}
2013-11-15 22:05:57 = SIRKOLPOL
{
http://pastebin.com/S4efNGPt
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?
}
2013-11-15 22:21:29 = Gynvael Coldwind
{
@SIRKOLPOL
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:

Nick:
URL (optional):
Math captcha: 8 ∗ 10 + 6 =