Programowanie w Języku C 2

Transkrypt

Programowanie w Języku C 2
Programowanie w Języku C 2
Laboratorium 3
Zarządzanie pamięcią. Wskaźniki i funkcja malloc().
Opracował: mgr inż. Leszek Ciopiński
Wskaźniki
Podobnie jak w języku Pascal, również język C oferuje dynamiczne zarządzanie pamięcią.
Podstawowym narzędziem pracy ze strukturami dynamicznymi jest wskaźnik. Deklaruje się go
poprzez wstawienie przed nazwą zmiennej symbolu asterysk (gwiazdka *). Przykład jego deklaracji
przedstawiono poniżej:
int *wsk1;
//wskaźnik na wartość typu int
Należy pamiętać, że deklaracja wskaźnika nie jest równoznaczna z rezerwacją pamięci na dane.
Ponadto rozmiar każdego wskaźnika jest taki sam, niezależnie od docelowego rozmiaru pamięci.
W celu odwołania się do wartości spod wskaźnika należy poprzedzić nazwę zmiennej symbolem
asterysk. Przykład:
*wsk1 = 5; // przypisanie wartości 5 do pamięci oznaczonej przez
// wskaźnik
wsk1 = 5; // zmiana adresu pamięci na który wskazuje wskaźnik
Istnieje też możliwość uzyskania wskaźnika do zmiennej zadeklarowanej statycznie przy pomocy
operatora oznaczonego symbolem ampersand (and &). Przykład:
int a, *wsk;
a=3;
wsk=&a; // po tej operacji prawdziwa jest równość: *wsk==a;
a=2;
// po tej operacji prawdziwa jest równość: *wsk==2;
sizeof()
Funkcja sizeof() jako parametr pobiera dowolną zmienną lub nazwę typu. Wartością zwracaną jest
rozmiar pamięci zajmowany przez daną zmienną lub typ wyrażoną w bajtach. W przypadku
wskaźników funkcja ta zwraca zawsze ten sam rozmiar, niezależnie od rozmiaru alokowanej
pamięci oraz tego, czy dana pamięć już została przydzielona czy nie. Przykłady:
int
a =
b =
//a
a, b, c;
sizeof(int);
sizeof(c);
==b
Programowanie w Języku C2
Laboratorium
strona: 1 z 3
malloc()
Funkcja malloc() jest w języku C podstawową funkcją do dynamicznej alokacji pamięci. Opis
funkcji przedstawiono poniżej:
#include <stdlib.h>
void *malloc(size_t size);
Jako parametr funkcja przyjmuje wielkość obszaru jaki ma zostać zaalokowany wyrażony
w bajtach. W praktyce najczęściej w celu określenia rozmiaru używa się funkcji sizeof(). Wartością
zwracaną przez funkcję malloc() w przypadku powodzenia jest wskaźnik na typ void. Dlatego
wartość tą należy rzutować w celu uzyskania odpowiedniego typu. W przypadku, gdy niemożliwe
było zarezerwowanie odpowiedniej ilości pamięci zwracana jest wartość NULL.
calloc()
Funkcja calloc() służy głównie do alokowania tablic. Jej opis jest następujący:
#include <stdlib.h>
void *calloc(size_t nelem, size_t elsize);
Parametr nelem określa ilu elementowa ma być tablica, a parametr elsize jaki jest rozmiar w bajtach
każdego z elementów. W przeciwieństwie do funkcji malloc(), funkcja calloc() dodatkowo po
zarezerwowaniu pamięci wypełnia wszystkie jego bity wartością 0. Podobnie jak w przypadku
funkcji malloc(), jeśli zwrócona wartość to NULL to znaczy, że operacja zakończyła się
niepowodzeniem. W przeciwnym przypadku zwrócony wskaźnik należy rzutować na odpowiedni
typ danych.
free()
Podstawowym sposobem zwolnienia uprzednio zarezerwowanej pamięci jest użycie funkcji free(),
której opis jest następujący:
#include <stdlib.h>
void free(void *ptr);
Jedynym parametrem przekazywanym funkcji jest wskaźnik na zwalniany obszar pamięci. Należy
pamiętać, że nie wolno zwalniać niezarezerwowanego obszaru pamięci, gdyż działanie programu
nie jest określone w takich przypadkach.
Przykład:
#define ROZMIAR 10
int i;
int **tabliczka = malloc(ROZMIAR * sizeof *tabliczka);
*tabliczka = malloc(ROZMIAR * ROZMIAR * sizeof **tabliczka);
for (i = 1; i<ROZMIAR; ++i) {
tabliczka[i] = tabliczka[0] + (i * ROZMIAR);
}
for (i = 0; i<ROZMIAR; ++i) {
int j;
Programowanie w Języku C2
Laboratorium
strona: 2 z 3
for (j = 0; j<ROZMIAR; ++j) {
tabliczka[i][j] = (i+1)*(j+1);
}
}
free(*tabliczka);
free(tabliczka);
Funkcja realloc() służy do zmiany rozmiaru obszaru (bloku) pamięci utworzonego przez malloc()
lub calloc(). Przyjmuje dwa parametry, pierwszym parametrem jest wskaźnik na obszar pamięci
(który chcemy zmienić), drugim natomiast nowy rozmiar obszaru.
void *realloc(wskaznik,rozmiar);
Zawartość obszaru pamięci (poddawanego modyfikacji) nie ulegnie zmianie (w przypadku gdy nowy
rozmiar jest większy od starego rozmiaru). Jeśli nowy rozmiar obszaru jest większy, dodatkowy
obszar nie jest inicjalizowany. Funkcja zwraca wskaźnik na nowy obszar lub NULL w przypadku
błędu.
Wypełnianie, kopiowanie i porównywanie pamięci
Funkcja memset() należy do standardowej biblioteki języka C, zadeklarowane jest w pliku
nagłówkowym <string.h>. Służy do ustawiania podanego obszaru pamięci dana wartością.
Przyjmuje trzy parametry, pierwszy określa miejsce docelowe (obszar pamięci), drugi parametr
oznacza wartość jako chcemy ustawić, ostatni parametr oznacza ilość miejsc w docelowym obszarze,
które chcemy ustawić.
memset(gdzie,wartosc,rozmiar);
Przykład:
memset(tablica1,0,sizeof(tablica1));
Funkcja memcpy() służy do kopiowania obszarów pamięci, przyjmuje trzy parametry. Pierwszy
parametr oznacza miejsce źródłowe, drugi miejsce docelowe, ostatni ilość bajtów do skopiowania.
memcpy(to,from,rozmiar);
Przykład:
char dane1[20],dane2[20];
memcpy(dane1, dane2, sizeof(dane1)); // dane2 -> dane1
Funkcja memcmp() służy do porównywania obszarów (bloków) pamięci o określonym rozmiarze,
zwraca analogiczne wartości co funkcja strcmp().
memcmp(wsk1,wsk2,rozmiar);
Przykład:
char dane1[20],dane2[20];
if(memcmp(dane1, dane2, sizeof(dane1)) == 0)
puts(”Identyczne”);
else puts(”Rozne”);
Źródło: pl.wikibooks.org
Programowanie w Języku C2
Laboratorium
strona: 3 z 3