
Управление свободной памятью
Из урока 1 вы узнали, что при выполнении ваши программы могут использовать оператор new для динамического распределения памяти из свободной памяти. Если оператор new успешно выделяет память, ваша программа получает на нее указатель. Если оператор new не может выделить требуемую память, он присваивает вашей переменной-указателю значение NULL. В зависимости от назначения вашей программы, вы, возможно, захотите, чтобы программа выполнила определенные операции, если new не может удовлетворить запрос на память. Из этого урока вы узнаете, как заставить C++ вызвать специальную функцию, еслиnew не может удовлетворить запрос на память. К концу данного урока вы освоите следующие основные концепции:
Вы можете создать свой собственный обработчик ситуации, когда памяти недостаточно — функции, которую C++ вызывает, если new не может удовлетворить запрос на память.
C++ позволяет вам определить собственный оператор new длявыделения и, возможно, инициализации памяти.
C++ позволяет вам определить собственный оператор delete для освобождения памяти.
Как вы узнаете, с помощью собственных операторов new и delete вы можете лучше управлять ошибками при недостаточности памяти.
Создание обработчика для операций со свободной памятью
Как вы уже знаете из урока 1, если оператор new не может выделить требуемую память из свободной памяти, он присваивает значение NULL вашей переменной-указателю. Следующая программа USE_FREE.CPP неоднократно вызывает оператор new, выделяя каждый раз 1000 байт, пока свободная память не исчерпается:
#include <iostream.h>
void main (void)
{ char *pointer; do
{ pointer = new char[1000]; if (pointer 1= NULL) cout << "Выделено 1000 байт" << endl; else cout << "Свободной памяти нет " << endl; } while (pointer); }
Как видите, программа просто выполняет цикл, пока new не присвоит указателю значение NULL. Если вы хотите, чтобы new выполнил другие действия (что-нибудь отличное от тупого возвращения значения NULL), когда он не может удовлетворить запрос на память, то сначала вам следует определить функцию, которую должна вызывать ваша программа, если памяти недостаточно для удовлетворения запроса. Например, следующая функция end_pro-gram выводит на экран сообщение, а затем использует функцию библиотеки этапа выполнения exit для завершения программы:
void end_program(void)
{ cout << "Запрос на память не может быть удовлетворен" << endl; exit(l); }
Чтобы заставить C++ вызывать функцию end_program, если new не может удовлетворить запрос на память, вам необходимо вызвать функциюset_new_handler, указав ей функцию end_program в качестве параметра, как показано ниже:
set_new_handler(end_program);
Следующая программа END_FREE.CPP вызывает функцию end_program,если new не может удовлетворить запрос на память:
#include <iostream.h>
#include <stdlib.h> // Прототип exit
#include <new.h> // Прототип set_new_handler
void end_program(void)
{ cout << "Запрос на память не может быть удовлетворен" << endl; exit(l); }
void main(void)
{ char* pointer; set_new_handler(end_program); do
{ pointer = new char[10000]; cout << "Выделено 10000 байт" << endl; } while (1); }
В данном случае программа просто завершается, если new не может выделить память из свободной памяти. В зависимости от потребностей вашей программы вы могли бы использовать функцию для выделения памяти из другого источника, например из расширенной памяти компьютера, которая существует в среде MS-DOS. Кроме того, ваша программа могла бы освободить память распределенную ею для других целей, чтобы сделать доступной свободную память. Обеспечивая вашим программам возможность создавать обработчик ситуации отсутствия памяти, C++ предоставляет вам полный контроль над процессом распределения памяти.