C/Wskaźniki: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
→Obsługa pamięci: czytelna poprawka (*tablica), poprawione dla pozostałych miejsc / int main jest tu całkowicie zbędny, w pozostałych fragmentach był też pominięty |
|||
Linia 219:
Załóżmy, że chcemy stworzyć tablicę liczb typu float:
<source lang="C">
int rozmiar;
float *tablica;
Linia 229 ⟶ 225:
tablica = (float*) malloc(rozmiar * sizeof(*tablica)); //pierwsza gwiazdka (*) w funkcji malloc() to operator mnozenia
tablica[0] = 0.1;
</source>
Przeanalizujmy teraz po kolei, co dzieje się w powyższym fragmencie. Najpierw deklarujemy 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. <tt>rozmiar * sizeof
W wielu książkach (również K&Rv2) i w Internecie stosuje się inny schemat użycia funkcji malloc a mianowicie: <tt>tablica = (float*)malloc(rozmiar * sizeof(float))</tt>. Takie użycie należy traktować jako błędne, gdyż nie sprzyja ono poprawnemu wykrywaniu błędów.
Linia 242 ⟶ 234:
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 <tt>tablica</tt> (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 <tt>void*</tt> 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 malloc, calloc i realloc odnoszące się do naszej tablicy i zmieniać wszędzie <tt>sizeof(float)</tt> na <tt>sizeof(double)</tt>. Aby temu zapobiec lepiej od razu użyć <tt>sizeof
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.
Linia 258 ⟶ 250:
Czasami możemy potrzebować zmienić rozmiar już przydzielonego bloku pamięci. Tu z pomocą przychodzi funkcja [[C/realloc|realloc]]:
<source lang="C">
tablica = realloc(tablica, 2*rozmiar*sizeof
</source>
Linia 271 ⟶ 263:
rozmiar = 3;
tablica = (float*) calloc(rozmiar, sizeof (*tablica));
tablica[0] = 0.1;
</source>
|