Скачиваний:
190
Добавлен:
05.07.2021
Размер:
16.53 Mб
Скачать

20. Особенности исчерпания памяти. Исключения, возникающие при исчерпании памяти. Пример использования.

Хотя современные машины имеют огромный объем памяти, всегда существует вероятность исчерпания динамической памяти. Как только программа использует всю доступную ей память, выражения с оператором new будут терпеть неудачу. По умолчанию, если оператор new неспособен зарезервировать требуемый объем памяти, он передает исключение типа bad_alloc.

+ См. вопрос 19

21. Время жизни динамически создаваемых объектов. Примеры использования.

Продолжительность их жизни не зависит от того, где они созданы. Динамические объекты существуют, пока не будут удалены явным образом. Динамические объекты размещаются в динамической памяти (free store).

Для управления динамическими объектами применяются операторы new и delete.

Оператор new выделяет место в динамической памяти для объекта и возвращает указатель на этот объект.

Оператор delete получает указатель на динамический объект и удаляет его из памяти.

1

2

3

int *p1 = new int(12);

std::cout << "p1: " << *p1 << std::endl;  // 0

delete p1;

22. Присваивание указателю значения nullptr. Примеры использования.

Помимо адресов памяти, есть ещё одно значение, которое указатель может хранить: значение null. Нулевое значение (или ещё «значение null») — это специальное значение, которое означает, что указатель ни на что не указывает. Указатель, содержащий значение null, называется нулевым указателем.

int *ptr(0);  // ptr теперь нулевой указатель

int *ptr1; // ptr1 не инициализирован

ptr1 = 0; // ptr1 теперь нулевой указатель

Разыменование нулевых указателей

Как мы уже знаем из предыдущего урока, разыменование указателей с мусором приведёт к неожиданным результатам. С разыменованием нулевого указателя дела обстоят так же. В большинстве случаев вы получите сбой в программе.

В редких случаях, использование 0 как аргумента-литерала может привести к проблемам, так как компилятор не сможет определить, используется ли нулевой указатель или целое число 0

Для решения этой проблемы, в C++11 ввели новое ключевое слово nullptr, которое также является константой r-value.

int *ptr = nullptr; // примечание: ptr по-прежнему остаётся указателем типа int, просто со значением null (0)

Пример использования:

void doAnything(int *ptr)

{

    if (ptr)

        std::cout << "You passed in " << *ptr << '\n';

    else

        std::cout << "You passed in a null pointer\n";

}

int main()

{

    doAnything(nullptr); // теперь аргумент является точно нулевым указателем, а не целочисленным значением

    return 0;

}

23. Использование указателя shared_ptr совместно с оператором new. Примеры использования.

shared_ptr Класс описывает объект, использующий подсчет ссылок для управления ресурсами. Объект shared_ptr фактически содержит указатель на ресурс, которым он владеет, или содержит пустой указатель (NULL). Обладать ресурсом могут несколько объектов shared_ptr; при удалении последнего объекта shared_ptr, обладающего тем или иным ресурсом, данный ресурс освобождается.

class Item

{

public:

Item() { std::cout << "Item acquired\n"; }

~Item() { std::cout << "Item destroyed\n"; }

};

int main()

{

// Выделяем Item и передаём его в std::shared_ptr

Item *item = new Item;

std::shared_ptr<Item> ptr1(item);

{

std::shared_ptr<Item> ptr2(ptr1); // используем оператор присваивания копированием для создания второго std::shared_ptr из ptr1, указывающего на тот же Item

std::cout << "Killing one shared pointer\n";

} // ptr2 выходит из области видимости здесь, но больше ничего не происходит

std::cout << "Killing another shared pointer\n";

return 0;

} // ptr1 выходит из области видимости здесь и выделенный Item уничтожается также здесь