Pracuję nad dynamicznie połączoną biblioteką (DLL) o krytycznym działaniu, która również powinna mieć stosunkowo mały rozmiar binarny. Ponieważ nie jawnie rzuca żadnych wyjątków, chciałbym wyłączyć obsługę wyjątków w ogóle. Jest jednak jeden wyjątek (niezamierzony kalambur): kiedy zabraknie pamięci (OOM), muszę zgłosić kod błędu do aplikacji, aby miał szansę poradzić sobie z wdziękiem. Baza kodu jest zbyt duża, aby sprawdzić każdą alokację indywidualnie i propagować błąd oraz zawiera zewnętrzny kod, którego nie powinienem dotykać. Dlatego chciałbym przechwycić wyjątki OOM w wyeksportowanych funkcjach moich bibliotek DLL.Jak zapewnić odporność na brak pamięci przy wyłączonych wyjątkach C++ (VS2010)?
Szybki test pokazuje, że po wyłączeniu wyjątków C++ w Visual C++ 2010 (tj. Flagi nie/EHa,/EHsc lub/EHs), nadal przeskakuje do bloku catch (std :: bad_alloc &) przy przydzielaniu zbyt dużej ilości pamięci .
Wygląda na to, że działa zgodnie z oczekiwaniami. Jednak otrzymuję następujące ostrzeżenie na poziomie 1: "Używany program obsługi wyjątków C4530: C++, ale semantykę odwijania nie włączono." Określ/EHsc ". MSDN twierdzi, że "obiekt z automatycznym przechowywaniem w ramce, między funkcją wykonującą rzut i funkcją rzucającą rzut, nie zostanie zniszczony".
Dokładnie, co bym tu stracił? W porządku jest pozostawienie rzeczy w stanie niezdefiniowanym, o ile wszystko, co zostało utworzone przez bibliotekę, może zostać usunięte, a aplikacja może zacząć od początku (jeśli tak wybierze). Czy istnieje duże ryzyko wycieku pamięci, której nie można odzyskać?
Czy biblioteki DLL używają oddzielnej puli pamięci? A jeśli tak, czy mogę go usunąć bez konieczności usuwania aplikacji z biblioteki DLL? Mogę z łatwością sprawić, że moja biblioteka zignoruje jakiekolwiek dalsze (wyeksportowane) wywołania funkcji, dopóki aplikacja nie wykona reinicjalizacji.
Dzięki za porady.
* Czy biblioteki DLL używają oddzielnej puli pamięci? * Http://stackoverflow.com/questions/10820114/do-statically-linked-dlls-use-a-different-heap-than-the-main-program – thang
* A jeśli tak, czy mogę go usunąć bez konieczności usuwania aplikacji z biblioteki DLL? * Tak, po prostu usuń rzeczy z nowego i uwolnij rzeczy z malloc. – thang
Brak obsługi wyjątków oznacza, że obiekty utworzone na stosie (i wewnątrz konstruktora, który się nie powiedzie) nie zostaną zniszczone. Jeśli masz zamiar wyjść, gdy dzieje się 'bad_alloc', to dobrze z tym, jak sądzę [dopóki nie masz dziwnych zasobów, które nie zostaną wyczyszczone przy wyjściu z programu - ale większość powinna]. Jeśli chcesz "kontynuować" po 'bad_alloc', kod będzie musiał śledzić obiekty i zniszczyć wszystkie obiekty utworzone w ramkach stosu pomiędzy' throw' i 'catch'. Możesz eksperymentować, pisząc mały kod, który ma wydruki w destruktorach. –