19.2.5. Раскрутка стека и вызов деструкторов
19.2.5. Раскрутка стека и вызов деструкторов
Когда возбуждается исключение, поиск его catch-обработчика – раскрутка стека – начинается с функции, возбудившей исключение, и продолжается вверх по цепочке вложенных вызовов (см. раздел 11.3).
Во время раскрутки поочередно происходят аномальные выходы из просмотренных функций. Если функция захватила некоторый ресурс (например, открыла файл или выделила из хипа память), он в таком случае не освобождается.
Существует прием, позволяющий решить эту проблему. Всякий раз, когда во время поиска обработчика происходит выход из составной инструкции или блока, где определен некоторый локальный объект, для этого объекта автоматически вызывается деструктор. (Локальные объекты рассматривались в разделе 8.1.)
Например, следующий класс инкапсулирует выделение памяти для массива целых в конструкторе и ее освобождение в деструкторе:
class PTR {
public:
PTR() { ptr = new int[ chunk ]; }
~PTR { delete[] ptr; }
private:
int *ptr;
};
Локальный объект такого типа создается в функции manip() перед вызовом mathFunc():
void manip( int parm ) {
PTR localPtr;
// ...
mathFunc( parm ); // возбуждает исключение divideByZero
// ...
}
Если mathFunc() возбуждает исключение типа divideByZero, то начинается раскрутка стека. В процессе поиска подходящего catch-обработчика проверяется и функция manip(). Поскольку вызов mathFunc() не заключен в try-блок, то manip() нужного обработчика не содержит. Поэтому стек раскручивается дальше по цепочке вызовов. Но перед выходом из manip() с необработанным исключением процесс раскрутки уничтожает все объекты типа классов, которые локальны в ней и были созданы до вызова mathFunc(). Таким образом, локальный объект localPtr уничтожается до того, как поиск пойдет дальше, а следовательно, память, на которую он указывает, будет освобождена и утечки не произойдет.
Поэтому говорят, что процесс обработки исключений в C++ поддерживает технику программирования, основной принцип которой можно сформулировать так: “захват ресурса – это инициализация; освобождение ресурса – это уничтожение”. Если ресурс реализован в виде класса и, значит, действия по его захвату сосредоточены в конструкторе, а действия по освобождению – в деструкторе (как, например, в классе PTR выше), то локальный для функции объект такого класса автоматически уничтожается при выходе из функции в результате необработанного исключения. Действия, которые должны быть выполнены для освобождения ресурса, не будут пропущены при раскрутке стека, если они инкапсулированы в деструкторы, вызываемые для локальных объектов.
Класс auto_ptr, определенный в стандартной библиотеке (см. раздел 8.4), ведет себя почти так же, как наш класс PTR. Это средство для инкапсуляции выделения памяти в конструкторе и ее освобождения в деструкторе. Если для выделения одиночного объекта из хипа используется auto_ptr, то гарантируется, что при выходе из составной инструкции или функции из-за необработанного исключения память будет освобождена.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Просмотр стека вызовов
Просмотр стека вызовов В отладчике можно вывести окно Call Stack со списком всех активных процедур и функций сценария. Для этого нужно выполнить команду View|Call Stack. Например, если вызвать это окно, находясь внутри функции MyFunc() в сценарии ForDebug.js, то в списке мы увидим название
Раскрутка
Раскрутка После того как вы сделаете свой сайт доступным широкой общественности, ни в коем случае не следует останавливаться на достигнутом и опускать руки. Пока эта самая общественность о вашем детище еще ничего не знает. Чтобы сделать сайт по-настоящему доступным,
Раскрутка за деньги
Раскрутка за деньги Если у вас нет времени, но есть деньги, то раскрутку можно поручить пользователям, занимающимся этим профессионально. Существует множество сайтов, предлагающих услуги по увеличению количества посетителей интернет-ресурсов. Найти их несложно:
1.7.5. Многоуровневая архитектура стека TCP/IP
1.7.5. Многоуровневая архитектура стека TCP/IP Этот пункт книги является необязательным: если вы считаете, что у вас уже достаточно знаний о протоколе TCP/IP, то можете перейти к следующим разделам, а к этому вернуться позже. Здесь будет описана многоуровневая архитектура
27.1.1. Многоуровневая архитектура стека TCP/IP
27.1.1. Многоуровневая архитектура стека TCP/IP Протокол TCP/IP был создан в конце 60-х — начале 70-х годов агентством DARPA Министерства Обороны США (U.S. Department of Defense Advanced Research Projects Agency). Основные этапы развития этого протокола отмечены в таблице 27.1.Этапы развития протокола TCP/IP Таблица
Глава 4 РАСКРУТКА БЛОГА
Глава 4 РАСКРУТКА БЛОГА Как и зачем раскручивать блог Цель раскрутки или продвижения блога очень простая — если ваш блог не раскручен, то вы ничего не заработаете.Представьте популярного эстрадного исполнителя: что было бы, если бы он пел не на сцене, а дома в душе? Стал
Бесплатная раскрутка сайта
Бесплатная раскрутка сайта Раскрутка сайта дело довольно муторное, отнимающее много времени. Но результат, как правило, положительный. Но, прежде чем вообще что-то раскручивать, необходимо привести сайт в порядок, провести правильную его внутреннюю оптимизацию.
12. Запуск и раскрутка
12. Запуск и раскрутка Этап запуска и раскрутки инфопродукта мы будем обсуждать в других интеллект-картах.Таким образом мы реализуем каждую нашу идею. Самые главные – первые пункты, когда вы определяете дату и сколько кусочков должны записывать в день, чтобы дойти до даты
5. Базовая раскрутка партнерки
5. Базовая раскрутка партнерки Что делать для привлечения партнеров?? Рассказывайте о партнерской программе везде, на всех ваших сайтах – продающих и не продающих.? У профессионалов вы наверняка видели в конце каждого продающего текста или мини-сайта упоминание о
2. Раскрутка и продвижение (60 % времени)
2. Раскрутка и продвижение (60 % времени) В инфобизнесе на продвижение тратится 60 % времени. Это настройка источников трафика, таких как Яндекс. Директ, или контроль этого процесса, если он у вас на аутсорсинге. Партнерская программа, продающие тексты, их улучшение,
8.3. Использование конструкторов и деструкторов для управления ресурсами (RAII)
8.3. Использование конструкторов и деструкторов для управления ресурсами (RAII) ПроблемаДля класса, представляющего некоторый ресурс, требуется использовать конструктор для получения этого ресурса и деструктор для его освобождения. Эта методика часто называется
11.3.2. Раскрутка стека
11.3.2. Раскрутка стека Поиск catch-обработчикадля возбужденного исключения происходит следующим образом. Когда выражение throw находится в try-блоке, все ассоциированные с ним предложения catch исследуются с точки зрения того, могут ли они обработать исключение. Если подходящее
18.5.3. Порядок вызова конструкторов и деструкторов
18.5.3. Порядок вызова конструкторов и деструкторов Виртуальные базовые классы всегда конструируются перед невиртуальными, вне зависимости от их расположения в иерархии наследования. Например, в приведенной иерархии у класса TeddyBear (плюшевый мишка) есть два виртуальных