Programowanie w systemie UNIX/Memory
Limity
edytujSprawdzamy limity [1] za pomocą komendy Basha:[2]
ulimit -a
Przykładowy wynik:
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 126505 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 126505 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
Pamięć a programowanie
edytujW uproszczeniu z punktu widzenia programisty pamięć[3][4] jest podzielona na:[5][6]
alokacja | wielkość | zmiana wielkości | ogranicznie wielkości | dostęp | zmienne | funkcje | |
---|---|---|---|---|---|---|---|
sterta | dynamiczna | duża | możliwa | pamięć fizyczna RAM | globalne i dynamiczne | malloc/free | |
stos | statyczna | mała | niemożliwa | wielkość stosu = ulimit -s = 8192 kB | LIFO | lokalne |
Błędne wykorzystanie pamięci powoduje:[9]
- Przepełnienie bufora[10]
- przepełnienie bufora stosu[11]
- przepełnienie sterty
- wycieki pamięci (wykrywanie za pomocą Valgrinda)[12]
i może powodować zagrożenia informatyczne [13]
Porządek bajtów i bitów (ang. byto order = endianess)
edytujWiesz zapewne, że podstawową jednostką danych jest bit, który może mieć wartość 0 lub 1. Kilka kolejnych bitów[14] stanowi bajt (dla skupienia uwagi, przyjmijmy, że bajt składa się z 8 bitów). Często typ short ma wielkość dwóch bajtów i wówczas pojawia się pytanie w jaki sposób są one zapisane w pamięci - czy najpierw ten bardziej znaczący - big-endian, czy najpierw ten mniej znaczący - little-endian.[15]
Skąd takie nazwy? Otóż pochodzą one z książki Podróże Guliwera, w której liliputy kłóciły się o stronę, od której należy rozbijać jajko na twardo. Jedni uważali, że trzeba je rozbijać od grubszego końca (big-endian) a drudzy, że od cieńszego (little-endian). Nazwy te są o tyle trafne, że w wypadku procesorów wybór kolejności bajtów jest sprawą czysto polityczną, która jest technicznie neutralna.
Sprawa się jeszcze bardziej komplikuje w przypadku typów, które składają się np. z 4 bajtów. Wówczas są aż 24 (4 silnia) sposoby zapisania kolejnych fragmentów takiego typu. W praktyce zapewne spotkasz się jedynie z kolejnościami big-endian lub little-endian, co nie zmienia faktu, że inne możliwości także istnieją i przy pisaniu programów, które mają być przenośne należy to brać pod uwagę.
Poniższy przykład dobrze obrazuje oba sposoby przechowywania zawartości zmiennych w pamięci komputera (przyjmujemy CHAR_BIT == 8
oraz sizeof(long) == 4
, bez bitów wypełnienia (ang. padding bits)): unsigned long zmienna = 0x01020304; w pamięci komputera będzie przechowywana tak:
adres | 0 | 1 | 2 | 3 | big-endian |0x01|0x02|0x03|0x04| little-endian |0x04|0x03|0x02|0x01|
Zobacz:
- sprawdzanie za pomocą lscpu
- konwersje w C
Źródła
edytuj- ↑ Size limit of an Array in gcc
- ↑ ulimit - opis
- ↑ Anatomy of a Program in Memory by Gustavo Duarte Jan 27th, 2009
- ↑ What Every Programmer Should Know About Memory by Ulrich Drepper
- ↑ management in C: The heap and the stack by Leo Ferres
- ↑ Layout of C Programs
- ↑ Stos w wikipedii
- ↑ Kopiec w wikipedii
- ↑ Bezpieczeństwo pamięci w ang. wikipedii
- ↑ Przepełnienie bufora
- ↑ Epilogues, Canaries, and Buffer Overflows by Gustavo Duarte Mar 19th, 2014
- ↑ Użycie Valgrinda do wykrywania wycieków pamięci
- ↑ Bezpieczeństwo teleinformatyczne
- ↑ Standard wymaga aby było ich co najmniej 8 i liczba bitów w bajcie w konkretnej implementacji jest określona przez makro CHAR_BIT zdefiniowane w pliku nagłówkowym limits.h
- ↑ betterexplained article: a-little-diddy-about-binary-file-formats