×
Namespaces

Variants
Actions

Стек очистки (Cleanup stack)

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: CleanupStack
Den123
Последнее редактирование: hamishwillee (09 Dec 2011)

При выполнении приложения не должно быть никаких утечек памяти - это очень важно, поэтому Вы должны предпринимать определенные действия, чтобы быть уверенными в том, что все выделенные в динамической памяти объекты будут удалены при выбрасывании исключения. Стек очистки предоставляет весь необходимый функционал для реализации этого подхода.

Класс CleanupStack, как и любой стек, определяет два основных метода PushL и Pop. Основная цель стека очистки сохранить указатели на выделенные в куче объекты и уничтожить эти объекты в случае возникновения исключительной ситуации.

Никогда не помещайте в стек очистки данные-члены класса. Если указатель на динамически созданный объект был сохранен в существующем объекте класса - он должен быть удален из стека очистки, так как за уничтожения этого объекта теперь отвечает деструктор объекта-владельца.

Для гарантированного уничтожения динамически созданных объектов всегда помещайте их в стек очистки.

Contents

Рассмотрим пример

CDemo* demo = new CDemo;
DangerousOperationL();
delete demo;

Если во время выполнения функции DangerousOperationL() произойдет сброс, объект demo НЕ БУДЕТ уничтожен, занятая им динамическая память НЕ БУДЕТ освобождена.

Решение проблемы - использование стека очистки

CDemo* demo = new CDemo();
CleanupStack:: PushL(demo);
DangerousOperationL();
CleanupStack:: PopAndDestroy();

В данном примере уничтожение объекта demo производится с помощью стека очистки. Если выполнение DangerousOperationL() прошло нормально, производится извлечение объекта из стека и его уничтожение одним вызовом CleanupStack:: PopAndDestroy(). Если же во время выполнения DangerousOperationL() произошел сброс, уничтожение объекта demo будет выполнено стеком очистки автоматически в контексте возникшего сброса. Соответственно, использование стека очистки является обязательным условием при создании программ под Symbian ОС.


Может ли во время выполнения CleanupStack::PushL() произойти сброс ?

Теоретически, да. Однако это не должно Вас беспокоить - данный вариант развития событий предусмотрен, поэтому в стеке очистки всегда есть хотя бы одна свободная позиция. Когда Вы помещаете ваш объект в стек очистки, он занимает имеющуюся свободную позицию, далее выполняется попытка выделить память для новой свободной позиции. Если памяти недостаточно - происходит сброс - Ваш объект, уже помещенный в стек, извлекается и уничтожается. На самом деле, стек очистки выделяет память сразу под несколько позиций и может не сразу освобождать память, выделенную для хранения указателей при вызове метода Pop(). Поэтому операции помещения/извлечения объектов из стека очистки являются очень эффективными.

Ссылки по теме

This page was last modified on 9 December 2011, at 02:34.
47 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×