DYNAMICZNA ALOKACJA PAMIĘCI 121 Przeanalizujmy teraz po kolei, co dzieje się w powyższym fragmencie. Najpierw dekla- rujemy zmienne — rozmiar tablicy i wskaźnik, który będzie wskazywał obszar w pamięci, gdzie będzie trzymana tablica. Do zmiennej rozmiar możemy w trakcie działania programu przypisać cokolwiek — wczytać ją z pliku, z klawiatury, obliczyć, wylosować — nie jest to istotne. rozmiar * sizeof *tablica oblicza potrzebną wielkość tablicy. Dla każdej zmiennej float potrzebujemy tyle bajtów, ile zajmuje ten typ danych. Ponieważ może się to różnić na rozmaitych maszynach, istnieje operator sizeof , zwracający dla danego wyrażenia rozmiar jego typu w bajtach. W wielu książkach (również K&Rv2) i w Internecie stosuje się inny schemat użycia funkcji malloc a mianowicie: tablica = (float*)malloc(rozmiar * sizeof(float)). Takie użycie należy traktować jako błędne, gdyż nie sprzyja ono poprawnemu wykrywaniu błędów. Rozważmy sytuację, gdy programista zapomni dodać plik nagłówkowy stdlib.h, wówczas kompilator (z braku deklaracji funkcji malloc) przyjmie, że zwraca ona typ int zatem do zmiennej tablica (która jest wskaźnikiem) będzie przypisywana liczba całkowita, co od razu spowoduje błąd kompilacji (a przynajmniej ostrzeżenie), dzięki czemu będzie można szybko poprawić kod programu. Rzutowanie jest konieczne tylko w języku C++, gdzie konwersja z void* na inne typy wskaźnikowe nie jest domyślna, ale język ten oferuje nowe sposoby alokacji pamięci. Teraz rozważmy sytuację, gdy zdecydujemy się zwiększyć dokładność obliczeń i zamiast typu float użyć typu double. Będziemy musieli wyszukać wszystkie wywołania funkcji mal- loc, calloc i realloc odnoszące się do naszej tablicy i zmieniać wszędzie sizeof(float) na sizeof(double). Aby temu zapobiec lepiej od razu użyć sizeof *tablica (lub jeśli ktoś woli z nawiasami: sizeof(*tablica)), wówczas zmiana typu zmiennej tablica na double* zostanie od razu uwzględniona przy alokacji pamięci. Dodatkowo, należy sprawdzić, czy funkcja malloc nie zwróciła wartości NULL — dzieje się tak, gdy zabrakło pamięci. Ale uwaga: może się tak stać również jeżeli jako argument funkcji podano zero. Jeśli dany obszar pamięci nie będzie już nam więcej potrzebny powinniśmy go zwolnić, aby system operacyjny mógł go przydzielić innym potrzebującym procesom. Do zwolnienia obszaru pamięci używamy funkcji free(), która przyjmuje tylko jeden argument — wskaźnik, który otrzymaliśmy w wyniku działania funkcji malloc(). free (addr); Należy pamiętać o zwalnianiu pamięci — inaczej dojdzie do tzw. wycieku pamięci —
... zobacz całą notatkę
Komentarze użytkowników (0)