C++/Zarządzanie pamięcią: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
Błąd w nazwie języka programowania |
rozszerzenie opisu new |
||
Linia 75:
Kolejną korzyścią jest możliwość przeciążania. Jednak to już jest temat na inny rozdział.
==Działanie w przypadku braku pamięci==
1. Domyślnie gdy przydział pamięci jest niemożliwy operator '''new''' zgłasza wyjątek '''std::bad_alloc''', np.
<source lang="cpp" highlight="1,7,10">
#include <new> // wyjątek std::bad_alloc
#include <cstdio>
int main() {
try {
char* p = new char[1000000000000];
} catch (std::bad_alloc& e) {
// std::bad_alloc::what
std::printf("Błąd alokacji: %s\n", e.what());
}
return 0;
}
</source>
2. Można wyłączyć zgłaszanie wyjątku, zamiast tego w przypadku braku pamięci zostanie zwrócony pusty wskaźnik ('''nullptr'''). W tym celu po słowie kluczowym '''new''' trzeba podać symbol '''std::noexcept''', np.
<source lang="cpp" highlight="1,5,10">
#include <new> // symbol std::nothrow
#include <cstdio>
int main() {
char* p = new (std::nothrow) char[1000000000000];
if (p == nullptr) {
std::puts("Brak pamięci");
}
return 0;
}
</source>
==Placement new==
Jak zostało powiedziane operator new wykonuje dwie operacje:
* zaalokowanie pamięci o żądanym rozmiarze,
* wywołanie konstruktorów (domyślnych lub wyspecyfikowanych).
Można jednak użyć specjalnego wywołania '''new''', tzw. "placement new", które jedynie wywołuje konstruktory na pamięci już zaalokowanej w innym miejscu; trzeba być jednak pewnym, że wskazany obszar pamięci jest odpowiedniego rozmiaru.
Jest to niezbyt powszechne użycie, ma też jedną wadę: nie działa operator '''delete''', trzeba ręcznie wywoływać destruktory obiektów. Zastosowanie tego mechanizmu ma głównie sens, gdy samodzielnie zarządzamy pamięcią, np. zawczasu rezerwujemy pamięć dla dużej liczby obiektów i w miarę potrzeb ją przydzielamy, oszczędzając tym samym czas na każdorazowe odwołanie do alokatora pamięci.
<source lang="cpp" highlight="12,14">
#include <new>
#include <cstdlib> // malloc
class Klasa {
int numer;
};
int main() {
void* wskaznik = malloc(sizeof(Klasa));
Klasa* obiekt = new (wskaznik) Klasa;
obiekt->~Klasa();
return 0;
}
</source>
<noinclude>
|