przejście do zawartości
zpr c++ quick reference
Narzędzia użytkownika
Zarejestruj się!
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Zarejestruj się!
Ostatnie zmiany
Menadżer multimediów
Indeks
Ślad:
wlasne_funkcje_obslugi_braku_pamieci
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
/*! * Autor: Marcin Kaczor U3ISI nr albumu: 192641 * Temat: Obsluga braku pamieci (praca domowa na ZPR) * * Problem: Podczas korzystania z dynamicznego przydzialu pamieci w jezyku C++ * (za pomoca operatora new) jesli nie uda sie zarezerwowac bloku pamieci * o odpowiednim rozmiarze, to zostanie rzucony wyjatek std::bad_alloc. * Sprawdzanie czy po każdym wywolaniu new nie zostal rzucony wyjatek jest * klopotliwe. Oczywiscie mozna uzywac wersji operatora new, ktora nie rzuca * wyjatkiem new (std::nothrow) Typ, ale wtedy pomijamy obsługę błędów. * * Opis: Bilbioteka standardowa udostepnia mozliwosc zdefiniowania wlasnej funkcji * obslugi braku pamieci za pomoca funkcji z biblioteki standardowej set_new_handler(). * Funkcja obslugi braku pamieci powinna uzyskac wiecej pamieci, rzucic wyjatek, * przerwac program lub chociaz ustawic inna funkcje obslugi (lub odinstalowac * obecna), bo program bedzie sie wykonywal w nieskonczonej petli. * * Zastosowanie: Glownym zadaniem funkcji obslugi braku pamieci jest uzyskanie * wiekszej ilosci pamieci (np. przez usuniecie nieuzywanych obiektow) tak aby * aplikacja mogla dzialac dalej, czasami jest to niemozliwe, funkcja ta jest tez * przydatna gdy nie chcemy przy kazdym tworzeniu nowego obiektu obslugiwac * wyjatku bad_alloc, w ten sposob, gdy juz wystapi problem braku pamieci mozemy * to obsluzyc w jednym miejscu i zamknac aplikacje w mniej brutalny sposob, mamy * szanse na pozamykanie polaczen, plikow oraz poinformowanie uzytkownika o tym co * sie stalo. * * Przyklad: Nizej zostanie przedstawiony przyklad klasy reprezentujacej obiekty * zajmujace duzo pamieci, obiekty beda rejestrowane w rejstrze przez ktory tez * jest mozliwy do nich dostep, rejestr bedzie usuwac obiekty gdy bedzie * potrzebna pamiec. */ #include <new> // zawiera funkcje set_new_handler #include <iostream> // obiekty cout, cerr, etc. #include <cstdlib> // exit() - awayjne wyjscie #include <vector> // wektor obietktow BigSize //! wielkosc bufora powiekszajacego rozmiar BigSize #define BS_SIZE 200000000 // deklaracja klasy Register potrzebna klasie BigSize class Register; //! Klasa BigSize /*! Klasa BigSize reprezentuje duze obiekty w pamieci, np. warstwy w zaawansowanym programie do obrobki grafiki rastrowej lub zapamietywanie histori zmian w obrazie. */ class BigSize { friend class Register; private: //! Prywatny konstruktor, tylko obiekty klasy Register maja prawo tworzyc obiekty //! BigSize. Dla celow testowych informuje uzytkownika o stworzeniu obiektu BigSize() { std::cout << "Creating BigSize..." << std::endl; } //! Prywatny konstruktor kopiujacy, zabezpiecza przed kopiowaniem obiektow, //! dostep do obiektu jest mozliwy tylko przez klase register BigSize(const BigSize &) {}; //! Prywatny destruktor, tylko obiekty klasy Register maja prawo niszczyc obiekty //! BigSize. Dla celow testowych informuje uzytkownika o usunieciu obiektu ~BigSize() { std::cout << "Deleting BigSize..." << std::endl; } private: //! Tablica znakow, bufor, w przykladzie tylko sztucznie powieksza rozmiar klasy char buffer_[BS_SIZE]; }; //! Klasa Register /*! Klasa Register tworzy, usuwa i przechowyje wskazania na obiekty BigSize, zaimplemneotwna jako Singleton, mozna przy implemntacji wykorzystac rowniez wzorzec fabryki */ class Register { private: //! Prywatny konstrukotr domyslny i kopiujacy Register() : counter_(0) {}; Register(const Register &r); public: //! Metoda pobierajaca referencje do obiektu static Register& getInstance() { static Register instance; return instance; } //! Tworzenie nowego obiektu klasy BigSize BigSize *getNewBigSize() { BigSize *bs = new BigSize(); objects_.push_back(bs); counter_++; return bs; } //! zwolnienie nieuzywanych obiektow, w tym przykladzie wszystkie obiekty sa nieuzywane //! metoda zwaraca true zostala zwolniona jakakolwiek ilosc pamieci, w przeciwnym razie false bool deleteUnusedObjects() { bool retval = counter_ > 0 ? true : false; while (counter_--) { delete objects_.back(); objects_.pop_back(); } counter_ = 0; return retval; } //! Pobranie obiektu klasy BigSize o zadanym indeksie, niewykorzystywane w przykladzie BigSize *getBigSize(int index) { if (index > 0 && index < counter_) return objects_[index]; else return NULL; } private: int counter_; /**< licznik obiektow */ std::vector<BigSize *> objects_; /**< wektor obiektow */ }; //! Funkcja obslugi braku pamieci, zamyka awaryjnie aplikacje void KillApplication() { // informacja dla uzytkownika, w zaleznosci od potrzeb moze byc zapisana do logu std::cerr << "Pamiec zostala wyczerpana, awaryjne zamykanie aplikacji." << std::endl; // awaryjne zamykanie aplikacji, zapisanie stanu, zamkniecie plikow, polaczen, etc. exit(1); } //! Funkcja obslugi braku pamieci, sprzata pamiec void CleanUpMemory() { // informacja dla uzytkownika, potrzebna raczej tylko dla aplikacji testowej std::cout << "Pamiec zostala wyczerpana, usuwanie niepotrzebnych obiektow." << std::endl; if (!Register::getInstance().deleteUnusedObjects()) { // nie udalo sie zwolnic pamieci std::set_new_handler(KillApplication); // ustawienie nowej funkcji obslugi braku pamieci return; } exit(1); // program moze kontynuowac dzialanie, bo zwolniono czesc nieuzywanej pamieci, // ale w tym przykladzie dzialalby w petli nieskonczonej, dlatego zostanie zamkniety } int main () { std::set_new_handler(CleanUpMemory); // ustawienie nowej funkcji obslugi braku pamieci for(;;) { Register::getInstance().getNewBigSize(); // zajmowanie pamieci :-) } return 0; }
wlasne_funkcje_obslugi_braku_pamieci.1228339491.txt.gz
· ostatnio zmienione: 2008/12/03 22:24 przez
marcinkaczor
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Do góry