malloc(3) Library Functions Manual malloc(3) NAZWA malloc, free, calloc, realloc, reallocarray - przydziela i zwalnia pamiec dynamiczna BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include void *malloc(size_t size); void free(void *_Nullable ptr); void *calloc(size_t nmemb, size_t size); void *realloc(void *_Nullable ptr, size_t size); void *reallocarray(void *_Nullable ptr, size_t nmemb, size_t size); Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)): reallocarray(): Od glibc 2.29: _DEFAULT_SOURCE glibc 2.28 i wczesniejsze: _GNU_SOURCE OPIS malloc() Funkcja malloc() przydziela pamiec o rozmiarze size bajtow i zwraca wskaznik do przydzielonej pamieci. Pamiec nie jest inicjowana. Jesli size wynosi 0, to malloc() zwraca unikatowa wartosc wskaznika, ktory potem mozna z powodzeniem przekazac do free() (zob. ,,Nieprzenosne zachowanie"). free() Funkcja free() zwalnia obszar pamieci wskazywany przez ptr, ktory zostal wczesniej przydzielony za pomoca wywolania malloc() lub funkcji powiazanych. W przeciwnym przypadku lub gdy ptr zostalo juz uwolnione, funkcja zachowa sie w sposob nieokreslony. Jesli ptr jest rowne NULL, nie zostanie wykonana zadna operacja. calloc() Funkcja calloc() przydziela pamiec dla tablicy o liczbie nmemb elementow o rozmiarze size bajtow kazdy i zwraca wskaznik do przydzielonej pamieci. Pamiec jest ustawiana na zero. Jesli nmemb lub size wynosi 0, to calloc() zwraca unikatowa wartosc wskaznika, ktora potem mozna z powodzeniem przekazac do free(). Jesli przemnozenie nmemb i size spowodowaloby przepelnienie liczby calkowitej, calloc() zwroci blad. Przepelnienie nie zostaloby natomiast wykryte w nastepujacym wywolaniu do malloc(), ktore spowodowaloby przydzielenie bloku pamieci o nieprawidlowym rozmiarze: malloc(nmemb * size); realloc() Funkcja realloc() zmienia rozmiar bloku pamieci wskazywanego przez ptr na size bajtow. Zawartosc pamieci nie zostanie zmieniona w zakresie od poczatku obszaru do minimum ze starego i nowego rozmiaru. Jesli nowy rozmiar jest wiekszy od starego, to dodana pamiec nie zostanie zainicjowana. Jesli ptr jest rowne NULL, to wywolanie jest rownowazne malloc(size) dla wszystkich wartosci size. jesli size jest rowne zeru i ptr jest rozny od NULL, to wywolanie jest rownowazne z free(ptr) (lecz zob. ,,Nieprzenosne zachowanie" w sprawie problemow z przenosnoscia). Jezeli ptr jest rozne od NULL, to musi on pochodzic z wczesniejszego wywolania malloc() lub powiazanych funkcji. Jesli wskazywany obszar zostal przemieszczony, to wykonywane jest free(ptr). reallocarray() Funkcja reallocarray() zmieni rozmiar (i ewentualnie przesunie) blok pamieci, na ktory wskazuje ptr, do wielkosci odpowiednio duzej dla tablicy nmemb elementow, kazdy z ktorych ma rozmiar size bajtow. Jest to rownowazne wywolaniu realloc(ptr, nmemb * size); Jednak w odroznieniu od tego wywolania realloc(), reallocarray() bezpiecznie zawiedzie w przypadku, w ktorym mnozenie prowadziloby do przepelnienia. Jesli takie przepelnienie wystapi, reallocarray() zwroci blad. WARTOSC ZWRACANA Funkcje malloc(), calloc(), realloc() i reallocarray() zwracaja wskaznik do przydzielonej pamieci, ktory jest odpowiednio wyrownany dla dowolnego typu, ktory miesci sie w zadanym lub mniejszym rozmiarze. W razie bledu funkcje te zwracaja NULL i ustawiaja errno. Proba przydzielenia wiecej niz PTRDIFF_MAX bajtow jest uwazana za blad, poniewaz tak duze obiekty moga pozniej spowodowac przepelnienie przy odjeciu wskaznika. Funkcja free() nie zwraca zadnej wartosci i zachowuje errno. Funkcje realloc() i reallocarray() zwracaja NULL jesli ptr nie wynosi NULL, a zadany rozmiar wynosi zero; nie jest to uwazane za blad (problemy z przenosnoscia opisano w rozdziale ,,Nieprzenosne zachowanie"). W innym przypadku, zadany wskaznik moze byc taki sam jak ptr, jesli alokacja nie zostala przesunieta (np. bylo miejsce na poszerzenie alokacji w miejscu) lub inny od ptr, jesli alokacje przeniesiono pod nowy adres. Jesli funkcje te zawioda, pierwotny blok pozostaje nienaruszony; nie jest zwalniany ani przesuwany. BLEDY calloc(), malloc(), realloc() i reallocarray() moga zawiesc z nastepujacym bledem: ENOMEM Brak wolnej pamieci. Prawdopodobnie aplikacje dotknal limit RLIMIT_AS lub RLIMIT_DATA opisany w getrlimit(2). Innym powodem, moze byc przekroczenie liczby mapowan okreslonej w /proc/sys/vm/max_map_count przez proces wywolujacy. ATRYBUTY Informacje o pojeciach uzywanych w tym rozdziale mozna znalezc w podreczniku attributes(7). +---------------------------+--------------------------+---------------+ |Interfejs | Atrybut | Wartosc | +---------------------------+--------------------------+---------------+ |malloc(), free(), | Bezpieczenstwo watkowe | MT-bezpieczne | |calloc(), realloc() | | | +---------------------------+--------------------------+---------------+ STANDARDY malloc() free() calloc() realloc() C11, POSIX.1-2008. reallocarray() Brak. HISTORIA malloc() free() calloc() realloc() POSIX.1-2001, C89. reallocarray() glibc 2.26. OpenBSD 5.6, FreeBSD 11.0. Od glibc 2.30, malloc() i powiazane funkcje odmowia rozmiarow wiekszych od PTRDIFF_MAX. free() zachowuje errno zaczynajac od glibc 2.33. UWAGI Linux stosuje optymistyczna strategie przydzielania pamieci. Oznacza to, ze gdy malloc() zwraca wartosc rozna od NULL, nie ma gwarancji, iz pamiec faktycznie jest dostepna. Jesli okaze sie, ze systemowi braklo pamieci, nieslawny zabojca OOM ("out-of-memory killer") zabije jeden lub wiecej procesow. Wiecej informacji zawiera opis plikow /proc/sys/vm/overcommit_memory i /proc/sys/vm/oom_adj w proc(5) oraz plik Documentation/vm/overcommit-accounting.rst w zrodlach jadra Linuksa. Zwykle malloc() przydziela pamiec ze sterty i ustawia wymagany rozmiar sterty, uzywajac sbrk(2). Podczas przydzielania blokow pamieci wiekszych niz MMAP_THRESHOLD bajtow, implementacja malloc() w glibc uzywa prywatnych anonimowych map z mmap(2). MMAP_THRESHOLD domyslnie wynosi 128 kB, ale mozna to zmienic za pomoca mallopt(3). Przed Linuksem 4.7, limit zasobow RLIMIT_DATA (patrz getrlimit(2)) nie mial zastosowania do pamieci przydzielonej przy uzyciu mmap(2); od Linuksa 4.7 limit ten stosuje sie rowniez dla alokacji dokonywanych za pomoca mmap(2). Aby uniknac uszkodzenia pamieci w aplikacjach wielowatkowych, funkcje te wewnetrznie stosuja muteksy, chroniace struktury danych odnoszace sie do zarzadzania pamiecia. W aplikacji wielowatkowej, w ktorej watki jednoczesnie przydzielaja i zwalniaja pamiec moga wystepowac oczekiwania na dostep do muteksow. Aby przydzial pamieci w aplikacji wielowatkowej byl skalowalny, biblioteka glibc tworzy dodatkowe areny przydzialu pamieci, jesli wykryte zostanie oczekiwanie na mutex. Kazda arena jest duzym regionem pamieci wewnetrznie zaalokowanym przez system (za pomoca brk(2) lub mmap(2)) i jest zarzadzana przy uzyciu jej wlasnych muteksow. Jesli dany program uzywa prywatnego alokatora pamieci, powinien to czynic przez zastapienie malloc(), free(), calloc() i realloc(). Funkcje zastepujace musza implementowac opisywane zachowania glibc, w tym obsluge errno, alokacje o zerowym rozmiarze i sprawdzanie przepelnienia; w innym przypadku inne funkcje biblioteczne moga sie zalamac lub dzialac niepoprawnie. Na przyklad, jesli zastepcze free() nie bedzie zachowywac errno, to pozornie niepowiazane funkcje biblioteczne moga zawodzic bez prawidlowej przyczyny w errno. Prywatne alokatory pamieci moga spowodowac koniecznosc zastapienia rowniez innych funkcji glibc; wiecej szczegolow w rozdziale ,,Replacing malloc" w podreczniku glibc. Zalamania w alokatorach pamieci sa niemal zawsze zwiazane z uszkodzeniami sterty, takimi jak przekroczenie rozmiaru przydzielonego fragmentu lub dwukrotne zwolnienie tego samego wskaznika. Implementacje malloc() mozna dostosowywac za pomoca zmiennych srodowiskowych. Szczegoly opisano w mallopt(3). Nieprzenosne zachowanie Zachowanie tych funkcji, gdy zadany rozmiar wynosi zero, zalezy od glibc; inne implementacje moga zwrocic NULL bez ustawienia errno, a przenosne programy POSIX powinny tolerowac takie zachowanie. Zob. realloc(3p). POSIX wymaga ustawiania errno przez alokatory pamieci, przy niepowodzeniu. Jednak standard C tego nie wymaga, dlatego aplikacje przenosne na platformy poza POSIX nie powinny zakladac takiego zachowania. Przenosne programy nie powinny uzywac prywatnych alokatorow pamieci, poniewaz POSIX i standard C nie dopuszczaja zastepowania malloc(), free(), calloc() i realloc(). PRZYKLADY #include #include #include #include #include #define MALLOCARRAY(n, type) ((type *) my_mallocarray(n, sizeof(type))) #define MALLOC(type) MALLOCARRAY(1, type) static inline void *my_mallocarray(size_t nmemb, size_t size); int main(void) { char *p; p = MALLOCARRAY(32, char); if (p == NULL) err(EXIT_FAILURE, "malloc"); strlcpy(p, "foo", 32); puts(p); } static inline void * my_mallocarray(size_t nmemb, size_t size) { return reallocarray(NULL, nmemb, size); } ZOBACZ TAKZE valgrind(1), brk(2), mmap(2), alloca(3), malloc_get_state(3), malloc_info(3), malloc_trim(3), malloc_usable_size(3), mallopt(3), mcheck(3), mtrace(3), posix_memalign(3) Szczegoly na temat implementacji biblioteki GNU C sa dostepne pod adresem . TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Andrzej Krzysztofowicz , Robert Luberda i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.9.1 2 maja 2024 r. malloc(3)