Programowanie w Języku C 2

Transkrypt

Programowanie w Języku C 2
Programowanie w Języku C 2
Laboratorium 1
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);
}
Programowanie w Języku C2
Laboratorium
strona: 2 z 3
for (i = 0; i<ROZMIAR; ++i) {
int j;
for (j = 0; j<ROZMIAR; ++j) {
tabliczka[i][j] = (i+1)*(j+1);
}
}
free(*tabliczka);
free(tabliczka);
Źródło: pl.wikibooks.org
Zadania:
1.
2.
3.
a)
b)
c)
d)
Napisz program, w którym zostanie zadeklarowana zmienna typu int i przypisz do niej
dowolną wartość. Następnie utwórz wskaźnik do tej zmiennej i przy jego pomocy wyświetl
wartość uprzednio wpisaną do zmiennej zadeklarowanej statycznie.
(1 punkt)
Napisz program, w którym zadeklarujesz typ strukturalny zawierający dwa pola: jedno typu
liczbowego i jedno typu tablicowego na napis. Następnie napisz funkcję, która jako parametry
przyjmuje dane do zapisania w strukturze i zwraca wskaźnik do niej. Funkcja ta musi
zaalokować miejsce dla tej struktury. Kolejnym elementem programu powinna być funkcja,
która jako parametr przyjmuje wskaźnik na strukturę i wyświetla wartość jej pól, po czym
zwalnia miejsce zajmowane przez tą strukturę.
(1 punkt)
Napisz program, który będzie posiadał czteroelementową tablicę wskaźników wskazujących
na strukturę zawierającą pola: imię, nazwisko i wiek. Program powinien posiadać funkcje:
dodaj – dodaje dane do struktury, do której wskaźnik umieszczany jest w tablicy na pierwszej
wolnej pozycji. Jeśli brakuje miejsca w tablicy, należy zwrócić informację o błędzie.
usuń – usuwa strukturę z tablicy o podanym indeksie i zwalnia zajmowaną przez nią pamięć
wyświetl – wyświetla wszystkie zapisane struktury w tablicy
wyczyść – program powinien usunąć wszystkie elementy tablicy i zwolnić całą zajmowaną
pamięć.
Należy utworzyć menu umożliwiające użytkownikowi na swobodne wybieranie funkcji, którą
chce wykonać.
(3 punkty)
Programowanie w Języku C2
Laboratorium
strona: 3 z 3