Последние записи
- TChromium (CEF3), сохранение изображений
- Как в Delphi XE обнулить таймер?
- Изменить цвет шрифта TextBox на форме
- Ресайз PNG без потери прозрачности
- Вывод на печать графического файла
- Взаимодействие через командную строку
- Перенести программу из Delphi в Lazarus
- Определить текущую ОС
- Автоматическая смена языка (раскладки клавиатуры)
- Сравнение языков на массивах. Часть 2
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - ttps://clck.ru/fCrQw
29th
Авг
УРОК 32. УПРАВЛЕНИЕ СВОБОДНОЙ ПАМЯТЬЮ
Posted by key under c/c++
Из урока 31 вы узнали, что при выполнении ваши программы могут использовать оператор new для динамического распределения памяти из свободной памяти. Если оператор new успешно выделяет память, ваша программа получает на нее указатель. Если оператор new не может выделить требуемую память, он присваивает вашей переменной-указателю значение NULL. В зависимости от назначения вашей программы, вы, возможно, захотите, чтобы программа выполнила определенные операции, если new не может удовлетворить запрос на память. Из этого урока вы узнаете, как заставить C++ вызвать специальную функцию, если new не может удовлетворить запрос на память. К концу данного урока вы освоите следующие основные концепции:
- Вы можете создать свой собственный обработчик ситуации, когда памяти недостаточно — функции, которую C++ вызывает, если new не может удовлетворить запрос на память.
- C++ позволяет вам определить собственный оператор new длявыделения и, возможно, инициализации памяти.
- C++ позволяет вам определить собственный оператор delete для освобождения памяти.
Как вы узнаете, с помощью собственных операторов new и delete вы можете лучше управлять ошибками при недостаточности памяти.
СОЗДАНИЕ ОБРАБОТЧИКА ДЛЯ ОПЕРАЦИЙ СО СВОБОДНОЙ ПАМЯТЬЮ
Как вы уже знаете из урока 31, если оператор 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++ предоставляет вам полный контроль над процессом распределения памяти.
СОЗДАНИЕ СОБСТВЕННЫХ ОПЕРАТОРОВ newИ delete
Как вы знаете, C++ позволяет вашим программам перегружать операторы. Аналогично вы можете перегрузить операторы new и delete, чтобы изменить их поведение. Например, предположим, что вы выделяете 100 байт памяти для хранения супер-секретных данных о вашей компании. Когда вы в дальнейшем освобождаете эту память с помощью оператораdelete, освобождается буфер, который содержал эту память, т.е. те самые 100 байт, содержащие супер-секретные данные о вашей компании. Предположим, корпоративный шпион (и программист) имеет доступ к вашему компьютеру, его программа теоретически может распределить тот же 100-байтный массив в памяти вашего компьютера и изучить ваши супер-секреты. Перегружая оператор delete, ваша программа может сначала заполнить этот буфер нулями или другими бессмысленными символами, а потом освободить эту память. Следующая программа MYDELETE.CPP перегружает оператор delete. Она сначала перезаписывает 100 байт, на которые указывает указатель, а затем освобождает память, используя для этого функцию библиотеки этапа выполнения free:
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
static void operator delete(void *pointer)
{
char *data = (char *) pointer;
int i;
for (i = 0; i < 100; i++) data = 0;
cout << «Секрет в безопасности!» << endl;
free(pointer);
}void main(void)
{
char *pointer = new char[100];
strcpy(pointer, «Секреты моей компании»);
delete pointer;
}
При запуске программа выделяет память для строкового массива с помощью оператора new. Затем она копирует секреты компании в эту строку. В дальнейшем программа использует перегруженный операторdelete для освобождения памяти. Внутри функции delete приведенный ниже оператор присваивает значение переменной pointer указателю на символьную строку:
char *data = (char *) pointer;
Символы (char *), которые называются оператором приведения типов,предназначены только для того, чтобы сообщить компилятору C++, что функция знает, что она присваивает указатель типа void (см. выше параметры функции) указателю типа char. Если вы опустите оператор приведения типов, программа не откомпилируется. Затем функция копирует нули в 100 байт буфера и освобождает память, используя для этого функцию библиотеки этапа выполнения free. Очень важно отметить, что эта функция (оператор delete) работает только с областью памяти размером 100 байт. Поскольку данная программа выделяет память только один раз, она работает корректно. Если вы измените программу таким образом, чтобы выделялось только десять байт памяти и не сделаете подобных изменений в этой функции, то она перезапишет 90 байт памяти, которые ваша программа, возможно, использовала для других целей, приведя к ошибке. Однако, используя функции библиотеки этапа выполнения, ваши программы могут получить больше информации о размере области памяти, на которую указывает определенный указатель.
Подобным образом следующая программа NEW_OVER.CPP перегружает оператор C++ new. В данном случае перегруженная функция помещает символьную строку «Учимся программировать на языке C++!» в начало выделяемой памяти:
#include <iostream.h>
#include <alloc.h>
#include <string.h>
static void *operator new(size_t size)
{
char *pointer;
pointer = (char *) malloc(size);
if (size > strlen( «Учимся программировать на языке C++!»))
strcpy(pointer, «Учимся программировать на языке C++!»);
return(pointer);
}void main(void)
{
char *str = new char[100];
cout << str << endl;
}
Как видите, функция new использует для выделения памяти функциюmalloc библиотеки этапа выполнения. Если размер выделяемой памяти достаточен для хранения строки «Учимся программировать на языке C++!», данная функция использует функцию strcpy библиотеки этапа выполнения для копирования строки в область памяти.
ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ
По мере того как ваши программы становятся более сложными, вы будете выделять память в процессе выполнения, используя оператор new. Из этого урока вы узнали, как изменить поведение оператора new, сначала определяя функцию-обработчик, которую вызывает ваша программа, еслиnew не может удовлетворить запрос на память, а затем с помощью перегрузки самого оператора new. Из урока 33 вы узнаете новые способы использования входного потока cm и выходного потока соut для усовершенствования возможностей ввода и вывода ваших программ. Прежде чем перейти к уроку 33, убедитесь, что вы изучили следующее:
- Если оператор new не может удовлетворить запрос на память, то по умолчанию он присваивает значение NULL соответствующему указателю.
- Если вашим программам необходима другая обработка в том случае, когда new не может удовлетворить запрос на память, ваши программы могут определить свои собственные обработчики. Используя функцию set_new_handler, программа может заставить new вызвать вашу функцию, если невозможно удовлетворить запрос на память.
- C++ позволяет вашим программам перегружать операторы newи delete. Однако, прежде чем это сделать, вы должны иметь четкое представление о свободной памяти (куче) и функциях библиотеки этапа выполнения, которые ею манипулируют.
Programming articles
Создание сайтов на шаблонах
Множество вариантов работы с графикой на канве
Шифруем файл с помощью другого файла
Перехват API функций — Основы
Как сделать действительно хороший сайт
Создание почтового клиента в Delphi 7
Применение паскаля для
решения геометрических задач
Управление windows с помощью Delphi
Создание wap сайта
Операционная система unix, термины и понятия
SQL враг или друг
Возникновение и первая редакция ОС UNIX
Оптимизация проекта в Delphi
Ресурсы, зачем нужны ресурсы
Термины программистов 20 века
Советы по созданию собственного сайта с нуля
Шифруем файл с помощью пароля
Фракталы — геометрия природы
Crypt — Delphi программа для шифрования
Рассылка, зачем она нужна и как ее организовать?
Учебник по C++ для начинающих программистов
Уроки для изучения ассемблера
Загадочный тип PCHAR
Средства по созданию сайтов
Операторы преобразования
классов is и as
Borland Developer studio 2006. Всё в одном
Создание базы данных в Delphi, без сторонних БД
Software engineering articles
Случайные статьи
Купить рекламу на сайте за 1000 руб
пишите сюда - alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту
пеллетные котлы
Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
- Delphi форумы
- Форумы C (Си)
- Форум .NET Frameworks (точка нет фреймворки)
- Форум Java (джава)
- Форум низкоуровневое программирование
- Форум VBA (вба)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)