Gdy system operacyjny ładuje proces do pamięci, inicjuje wskaźnik stosu do adresu wirtualnego, w którym zdecydował, gdzie powinien iść stos w wirtualnej przestrzeni adresowej procesu, a kod programu używa tego rejestru, aby wiedzieć, gdzie znajdują się zmienne stosu. Moje pytanie brzmi: w jaki sposób malloc() wie, na jakim wirtualnym adresie zaczyna się hałda? Czy sterty zawsze istnieją na końcu segmentu danych, jeśli tak, to jak funkcja malloc() wie, gdzie to jest? Czy jest to nawet jeden ciągły obszar pamięci lub po prostu losowo przeplatany z innymi zmiennymi globalnymi w sekcji danych?W jaki sposób malloc() wie, gdzie zaczyna się hałda?
Odpowiedz
malloc
implementacje zależą od systemu operacyjnego; jest to proces, którego używają, aby uzyskać początek sterty. W systemie UNIX można to osiągnąć, wywołując sbrk(0)
w czasie inicjalizacji. W innych systemach operacyjnych proces jest inny.
Pamiętaj, że możesz wdrożyć malloc
bez znajomości położenia sterty. Możesz zainicjować bezpłatną listę na NULL
i wywołać sbrk
lub podobną funkcję z rozmiarem alokacji za każdym razem, gdy nie zostanie znaleziony wolny element o odpowiednim rozmiarze.
Ahah, światło włącza się. Właśnie tego szukałem. – mclaassen
Inna wspomniana odpowiedź była myląca z powodu tego wiersza "Wywołanie systemowe sbrk przesuwa" granicę "segmentu danych." I z mojego rozumienia segmentu danych zapisuje dane globalne. Tak więc założyłem, że kupa musi znajdować się na końcu segmentu danych, ale nie rozumiem, w jaki sposób malloc() mógł wiedzieć, gdzie był koniec. – mclaassen
W systemie Windows używa się Heap functions do pobierania pamięci sterty procesowej. Środowisko wykonawcze C przydzieli bloki pamięci na stercie za pomocą HeapAlloc
, a następnie użyje go do spełnienia żądań malloc
.
To tylko o implementacje Linuksa malloc
Wiele malloc
implementacji w systemie Linux lub POSIX użyć mmap(2) syscall trochę dość duży zakres pamięci. następnie mogą użyć munmap(2), aby je zwolnić.
(Wygląda sbrk(2) nie może być używany wiele dłużej; w szczególności nie jest ASLR przyjazny i może nie być wielowątkowego przyjazną)
Oba te syscalli może być dość ekspansywny, tak niektóre implementacje wymagają pamięci (używając mmap
) w dość dużych porcjach (np. w kawałku jednego lub kilku megabajtów). Następnie zarządzają wolną przestrzenią, np. powiązane listy bloków itp. Będą obsługiwać różne małe mallocs i duże mallocs.
mmap
syscall zwykle nie rozpocząć podając zakres pamięci w pewnych stałych elementów (w szczególności z powodu ASLR
Spróbuj w systemie uruchomić prosty program drukowania wynik pojedynczy malloc
(EG 128 int
. - s). prawdopodobnie będzie obserwować różne adresy z jednego biegu na drugi (z powodu ASLR). i strace(1) -ing jest bardzo pouczająca. Spróbuj również cat /proc/self/maps
(lub wydrukować linie /proc/self/maps
wewnątrz programu). Patrz proc(5)
Więc nie ma potrzeby "zaczynać" th e sterty pod jakimś adresem i na wielu systemach, które nie mają żadnego sensu. Jądro podaje segmenty wirtualnych adresów na losowych stronach.
BTW, zarówno GNU libc i musl libc są free software. Powinieneś zajrzeć do kodu źródłowego swojej implementacji malloc
. Uważam, że source code of musl libc jest bardzo czytelny.
- 1. W jaki sposób bash wie, gdzie kończą się moje nazwy zmiennych?
- 2. W jaki sposób bios wie, jaki rodzaj BPB jest obecny?
- 3. Gdzie zaczyna się deklaracja JUnit Matcher #?
- 4. Podczas konwersji łańcucha zakodowanego w utf-8 z bajtów na znaki, w jaki sposób komputer wie, gdzie kończy się znak?
- 5. W jaki sposób C# wie, jaki jest typ literału?
- 6. W jaki sposób Apache Spark wie o węzłach danych HDFS?
- 7. W jaki sposób JVM wie, gdzie można złapać wyjątek w czasie wykonywania?
- 8. Wyszukiwanie w języku SQL, gdzie ciąg zaczyna się od X
- 9. W jaki sposób Linux Kernel wie, gdzie szukać oprogramowania układowego sterownika?
- 10. W jaki sposób widok wie, którego układu użyć? Gdzie jest domyślny?
- 11. W jaki sposób są realizowane malloc i free?
- 12. W jaki sposób czytnik RSS wie, że kanał jest aktualizowany?
- 13. W jaki sposób Chocolatey wie, które pakiety są zainstalowane lokalnie?
- 14. W jaki sposób Bundler wie, z jakiego środowiska korzystać?
- 15. W jaki sposób Java wie jak modyfikować tablicę?
- 16. W jaki sposób kompilator wie, który blok catch ma wykonać?
- 17. w jaki sposób activerecord wie, jak wykonać wstawianie lub aktualizację?
- 18. W jaki sposób proces node.js wie, kiedy należy zatrzymać?
- 19. W jaki sposób Perl wie, że plik jest binarny?
- 20. Wybierz wszystko, gdzie [pierwsza litera zaczyna się od B]
- 21. W jaki sposób mogę zapytać kolumnę całkowitą o "zaczyna się z" w Entity Framework?
- 22. W jaki sposób fread wie, kiedy plik kończy się w C?
- 23. awscli zaczyna się błąd
- 24. Jaki jest najskuteczniejszy sposób sprawdzenia, czy ciąg zaczyna się od określonej litery w TCL?
- 25. Jaki jest poprawny i idiomatyczny sposób sprawdzenia, czy ciąg zaczyna się od określonej postaci w Rust?
- 26. W jaki sposób StackOverflow wie, kiedy pojawiają się nowe odpowiedzi na pytanie?
- 27. zaczyna się .. czy w OCaml syntaktycznym cukrze?
- 28. Postgres nie wie gdzie znaleźć konfigurację serwera
- 29. W jaki sposób implementuje się Wami Recorder?
- 30. W jaki sposób dostosowuje się stronę sklepu z aplikacjami Mac?
Może to być zakodowane na stałe. –
Wyobrażam sobie, że będzie to zależne od platformy.Czy chcesz uzyskać odpowiedź na konkretną platformę? –
możliwy duplikat [Jak działają malloc() i free()?] (Http://stackoverflow.com/questions/1119134/how-do-malloc-and-free-work) – ControlAltDel