node82






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,

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:
node82
node82 QVY4MZU7P43YWLKJLR36UPZYMDNINQOD4TXZZXA
node82
node82 GFVKCVGCP53LHOCSUVW4L555ONSQWXDAYQ6YCKI
node82
node82

więcej podobnych podstron