Zaawansowane CPP/Ćwiczenia 14: Zarządzanie pamięcią: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
(Nie pokazano 10 wersji utworzonych przez jednego użytkownika) | |||
Linia 23: | Linia 23: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | ||
Przykładowe rozwiązanie znajduje się w pliku [ | Przykładowe rozwiązanie znajduje się w pliku [[media:Linked_pool.h | linked_pool.h]]. | ||
</div></div> | </div></div> | ||
Linia 69: | Linia 69: | ||
}; | }; | ||
Całość kodu można zobaczyć w pliku [ | Całość kodu można zobaczyć w pliku [[media:Linked_new.h | linked_new.h]]. | ||
Z klasy <tt>linked_pool_new</tt> korzystamy dziedzicząc z niej: | Z klasy <tt>linked_pool_new</tt> korzystamy dziedzicząc z niej: | ||
Linia 91: | Linia 91: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | ||
Przykładowy alokator oparty o funkcję <tt>malloc</tt> jest | Przykładowy alokator oparty o funkcję <tt>malloc</tt> jest | ||
zaimplementowany w pliku [ | zaimplementowany w pliku [[media:Mallocator.h | mallocator.h]]. Funkcje <tt>allocate</tt> i <tt>deallocate</tt> są tak | ||
zdefiniowane, że wypisują informacje o rozmiarze i ilości alokowanych | zdefiniowane, że wypisują informacje o rozmiarze i ilości alokowanych | ||
elementów: | elementów: | ||
Linia 133: | Linia 133: | ||
dealokacji pamięci. | dealokacji pamięci. | ||
Implementując alokator oparty o <tt>linked_pool</tt> znów musimy uważać na | Implementując alokator oparty o <tt>linked_pool</tt> znów musimy uważać na sposób przydziału pamięci dla puli. Ponieważ musimy zapewnić równoważność iteratorów, każda lista musi alokować pamięć z tej samej puli. Pula będzie więc składową statyczną alokatora. Z powodu mechanizmu <tt>rebind</tt> nie możemy jednak teraz przydzialać pamięci dla puli dynamicznie, tak jak to robiliśmy w <tt>linked_pool_new</tt>. Dlatego rozmiar puli będzie podawany jako drugi argument szablonu alokatora: | ||
sposób przydziału pamięci dla puli. Ponieważ musimy zapewnić | |||
równoważność iteratorów, każda lista musi alokować pamięć z tej samej | |||
puli. Pula będzie więc składową statyczną alokatora. Z powodu | |||
mechanizmu <tt>rebind</tt> nie możemy jednak teraz przydzialać pamięci dla | |||
puli dynamicznie, tak jak to robiliśmy w <tt>linked_pool_new</tt>. Dlatego | |||
rozmiar puli będzie podawany jako drugi argument szablonu alokatora: | |||
template <class T,size_t N> class pool_allocator { | template <class T,size_t N> class pool_allocator { | ||
private: | private: | ||
Linia 149: | Linia 143: | ||
template<class T,size_t N> linked_pool<T> pool_allocator<T,N>::_pool(N); | template<class T,size_t N> linked_pool<T> pool_allocator<T,N>::_pool(N); | ||
(składowe statyczne inicjalizowane są poza klasą). | (składowe statyczne inicjalizowane są poza klasą). Wyrażenie <tt>rebind</tt> ma teraz postać: | ||
Wyrażenie <tt>rebind</tt> ma teraz postać: | |||
template <class U> | template <class U> | ||
struct rebind { typedef pool_allocator<U,N> other; }; | struct rebind { typedef pool_allocator<nowiki><U,N></nowiki> other; }; | ||
Całość kodu jest zamieszczona w pliku [[media:Pool_allocator.h | pool_allocator.h]]. Z tak zdefiniowanego alokatora korzysta się następująco: | |||
std::list<int,pool_allocator<int,10000> > l; | |||
</div></div> | </div></div> |
Aktualna wersja na dzień 10:51, 2 paź 2006
Ćwiczenie 1
Przerób przykłady z wykładu.
Ćwiczenie 2
Napisz własną implementację puli pamięci opartą o listę. Zasobnik powinien być szablonem przyjmującym jako parametr typ obiektów, dla których będzie przydzielał pamięć. Wielkość puli powinna być podawana w konstruktorze. Jeśli zażądamy za dużo pamięci, to powinien zostać rzucony wyjątek std::bad_alloc. Jeśli wyczerpie się pamięć w puli, żądanie przydziału powinno rzucić std::bad_alloc:
template<typename T> linked_pool {
linked_pool(size_t n) throw(std::bad_alloc); void *allocate() throw(std::bad_alloc); /*przydziela pamięc na jeden obiekt T*/ void deallocate(void *p) throw ();
release() throw (); /*zwalnia całą pamięć z puli*/ ~linked_pool() throw() ; }
Ćwiczenie 3
W oparciu o linked_pool
zaimplementuj klasę
z własnymi operatorami new
i delete
. Zaimplementuj klasę
tak, aby można było z niej dziedziczyć i w ten sposób łatwo
implementować new
i delete
w dowolnej klasie.
Ćwiczenie 4
Przerób nieznacznie alokator podany na wykładzie, tak aby jego funkcje wypisywały informacje o tym co robią. Użyj go z różnymi typami pojemników. Co możesz powiedzieć o sposobie przydziału pamięci dla różnych kontenerów?
Ćwiczenie 5
W oparciu o linked_pool
napisz własny alokator pamięci.
Do jakich pojemników będzie można go stosować?.