12.5 Zarządzanie pamięcią w C
Dalej: 12.6 Funkcje operujące na
W górę: 12. Zarządzanie pamięcią
Wstecz: 12.4 Dynamiczne tablice wielowymiarowe
12.5 Zarządzanie pamięcią w C
Operatory
new i
delete są charakterystyczne dla
języka C++. W C podobne zadania realizowane są za pomocą innych
funkcji - aby z nich korzystać, należy dołączyć plik
nagłówkowy
cstdlib. Ponieważ stosuje je się
bardzo często w istniejącym kodzie, omówimy je tu pokrótce. Nawet
zresztą pisząc w C++ używa się czasem funkcji z C, gdyż bywają
efektywniejsze, choć bardziej niebezpieczne i trudniejsze
w programowaniu.
Funkcja
malloc
(ang. memory allocation)
przydziela obszar w pamięci wolnej. Jej prototyp ma postać
void* malloc(size_t size);
Typ
size_t
jest typem całościowym, który może zależeć
od implementacji (zwykle jest tożsamy z
unsigned int). Funkcja
malloc alokuje
size bajtów pamięci dynamicznej
i zwraca wskaźnik do początku zarezerwowanego obszaru jako wskaźnik
typu
void*. Nie ma tu rozróżnienia między
alokowaniem pamięci na pojedynczy obiekt i na tablicę;
zawsze musimy podać liczbę bajtów. Funkcja
malloc
jest rzeczywiście funkcją, wywołuje się ją zatem podając
argument w nawiasach okrągłych. Zwraca surowy adres w pamięci, bez
żadnej informacji o typie obiektów, jakie będą tam wpisane.
A zatem przed przypisaniem tego adresu do zmiennej wskaźnikowej pewnego
typu należy dokonać odpowiedniej konwersji, czego nie musieliśmy
robić w przypadku operatora
new. Na przykład
1. int* k = (int*) malloc(sizeof(int));
2. *k = 5;
3. // ...
4. int size;
5. cin >> size;
6. int* m = (int*) malloc(size*sizeof(int));
7. for (int i = 0; i < size; ++i)
8. m[i] = 2*i;
Zauważmy, że nawet alokując pamięć na pojedynczą zmienną
w linii pierwszej tego przykładu musieliśmy jawnie podać
liczbę potrzebnych bajtów. W przypadku niepowodzenia funkcja
malloc zwraca wskaźnik zerowy. Przydzielona pamięć
nie jest w żaden sposób inicjowana.
Za pomocą innej funkcji,
calloc,
możemy zaalokować
obszar pamięci i od razu go zainicjować zerami. Prototyp
ma postać
void* calloc(size_t count, size_t size);
Parametr
count oznacza liczbę elementów, jakie alokowany
obszar ma pomieścić, a
size rozmiar (w bajtach) jednego
elementu. Zatem, aby zaalokować tablicę liczb całkowitych
i zainicjować ją zerami, można napisać
int dim;
cin >> dim;
int* tab = (int*) calloc(dim,sizeof(int));
Istnieje również funkcja
realloc
zmieniająca rozmiar bloku pamięci
dynamicznej wcześniej zaalokowanego:
void* realloc(void* ptr, size_t size);
której pierwszym argumentem jest wskaźnik zwrócony wcześniej przez
malloc,
calloc lub
realloc,
a
size jest nowym rozmiarem.
Jeśli rozmiar
size jest większy niż ten który został
podany przy wywołaniu funkcji
malloc,
to zostanie zarezerwowany nowy obszar o zwiększonym rozmiarze,
a zawartość poprzedniego bloku pamięci zostanie do niego skopiowana,
po czym stary obszar zostanie zwolniony.
Funkcja zawsze zwraca adres nowego obszaru, który jednak może
pokrywać się ze starym, jeśli
size wcale nie jest większe
od dotychczasowego rozmiaru.
W przypadku niepowodzenia
realloc zwraca wskaźnik zerowy
(czyli, w tradycyjnym C,
NULL), a dotychczasowy blok pamięci
pozostaje nienaruszony.
W tradycyjnym C do zwalniania pamięci dynamicznej służy funkcja
free
void free(void* ptr);
Argument
ptr musi być wskaźnikiem zawierającym dokładnie
ten sam adres, który zwrócony został przez funkcję
malloc,
calloc lub
realloc podczas
alokacji (lub realokacji).
Obszar pamięci zaalokowany za pomocą operatora
new
należy zwalniać za pomocą
delete (lub
delete[]).
Jeśli do przydzielenia pamięci użyto funkcji
malloc,
calloc lub
realloc, to zwolnić ją trzeba
za pomocą funkcji
free.
Podobnie jak nie należy mieszać
new i
delete
tablicowych z nietablicowymi, nie wolno też mieszać funkcji
przydzielających pamięc z C z funkcjami zwalniającymi pamięć
z C++ i odwrotnie.
Dalej: 12.6 Funkcje operujące na
W górę: 12. Zarządzanie pamięcią
Wstecz: 12.4 Dynamiczne tablice wielowymiarowe
T.R. Werner, 24 wrzesnia
2007, godz. 22:51
Wyszukiwarka
Podobne podstrony:
node82node82 QVY4MZU7P43YWLKJLR36UPZYMDNINQOD4TXZZXAnode82node82 GFVKCVGCP53LHOCSUVW4L555ONSQWXDAYQ6YCKInode82node82więcej podobnych podstron