Программирование >>  Формирование пользовательского контейнера 

1 ... 16 17 18 [ 19 ] 20 21 22 ... 156


return 1;

*р = 88;

cout Value at p is: *p endl; int к = *p;

cout k is к endl; return 0;

Далее приводится вывод программы с включенным режимом отображения (напоминаю, что вы можете наблюдать действие сборщика мусора, определив макрос DISPLAY в файлс gc.h).

Constructing GCPtr. Value at p is: 88 к is 88

GCPtr going out of scope.

Before garbage collection for gclist<int, 0>: memPtr refcount value

[002F12C0] 0 88

[00000000] 0

Deleting: 88

After garbage collection for gclist<int, 0>: memPtr refcount value

- Empty -

Когда профамма заверщается, объект р уходит за пределы области видимости. Это приводит к вызову деструктора, который уменьшает на единицу счетчик ссылок, связанный с памятью, на которую указывает объект р. Поскольку на эту память ссылается только указатель р, уменьшение связанного с ним счетчика ссылок делает его значение равным нулю. Затем деструктор объекта р вызывает функцию collect (), которая ищет в списке gclist элементы, счетчики ссылок которых равны нулю. У элемента списка, ранее связанного с объектом р, счетчик ссылок содержит нулевое значение, следовательно, память, на которую указывает этот объект, освобождается.



ЭЙНстинг 2.3. Более интересный пример

Показывает выход объекта GCPtr за пределы области видимости

до завершения программы, ♦include <iostreain> ♦include <new> ♦include gc.h

sing namespace std;

Еше одно замечание: до сбора мусора в списке gclist присутствует элемент пустым указателем. Этот указатель был сформирован, когда создавался объект р. Напомню, что если объекту GCPtr не задать начального адреса, то используется пустой или неопределенный адрес (который равен нулю). Хотя технически нет необходимости запоминать пустой адрес в списке gclist (так как он никогда не освобождается), подобное действие упрощает обработку других объектов типа GCPtr , поскольку гарантирует включение каждого из них в список gclist.

обработка исключений, связанных с выделением памяти

Как было показано в листинге 2.2, поскольку сборщик мусора не меняет способ выделения памяти с помощью операции new, вы должны обрабатывать сбои, возникающие при вьшелении памяти, как обычно, с помощью исключения bad alioc (ЭТО исключение генерируется, когда операция new выполняется с ошибкой). Конечно, профамма листинга 2.2 не вышла бы за пределы доступной памяти и блок try/catch ей на самом деле не нужен, но реальные приложения могут исчерпать память из хип-области. Следовательно, вы должны учитывать такую возможность и включать соответствующую проверку в ваши приложения.

Как правило, лучшая реакция на возникшее исключение bad alloc при использовании сбора мусора - вызов функции collect о для очистки любой неиспользуемой памяти и повторная попытка выделения памяти. Этот технический прием применяется в профамме тестирования на зафузку (load-testing program), приведенной далее в этой главе. Вы тоже можете его использовать в своих приложениях.

Более интересный пример

в листинге 2.3 приводится пример профаммы, демонстрирующий эффект выхода объекта GCPtr за пределы области видимости до ее завершения.



int main О ( GCPtr<int> p; GCPtr<int> q;

try {

p = new int(10); q = new int(11);

cout Value at p is: *p endl; cout Value at q is: *q endl;

cout Before entering block.\n ;

Теперь создадим локальный объект. { Начало блока.

GCPtr<int> г = new int(12);

cout Value at r is: *r endl; } Конец блока, вызывагаций выход г за пределы области видимости.

cout After exiting block.\n ;

} catch(bad alloc exc) {

cout Allocation failure!\n ; return 1;

cout Done\n ; retiJim 0;

Если включен режим отображения, приведенная программа выводит на экран следующую информацию. Constructing GCPtr. Constructing GCPtr. Value at p is: 10 Value at q is: 11 Before entering block.



1 ... 16 17 18 [ 19 ] 20 21 22 ... 156

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика