+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 92.51 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

Уроки программирования на Visual C++. Управление свободной памятью в C++.

21.06.2012 10:14
The_Programmer

СОЗДАНИЕ ОБРАБОТЧИКА ДЛЯ ОПЕРАЦИЙ СО СВОБОДНОЙ ПАМЯТЬЮ

Как вы уже знаете из урока Использование свободной памяти в С++, если оператор  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[i] = 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, убедитесь, что вы изучили следующее:

    1. Если оператор  new  не может удовлетворить запрос на память, то по умолчанию он присваивает значение NULL соответствующему указателю.
    2. Если вашим программам необходима другая обработка в том случае, когда  new  не может удовлетворить запрос на память, ваши программы могут определить свои собственные обработчики. Используя функцию  set_new_handler,  программа может заставить  new  вызвать вашу функцию, если невозможно удовлетворить запрос на память.
    3. C++ позволяет вашим программам перегружать операторы  new  и  delete.  Однако, прежде чем это сделать, вы должны иметь четкое представление о свободной памяти (куче) и функциях библиотеки этапа выполнения, которые ею манипулируют.

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

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям.

Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе.

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



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года