- •Управление esc – последовательность (с примерами)
- •4. Определение констант и их характеристика (const,define,enum)
- •5. Форматные потоки в с. Функции fPrintf(), Fscanf(), и модификации (с примерами). Спецификаторы
- •7. Перегруженные операции.
- •8. Инструкция ветвления. (пример)
- •9. Инструкция switch()
- •10. Применение инструкции switch() для создания текстового меню.
- •11. Инструкция цикла.
- •12. Инструкция перехода.
- •13. Указатели. Операции над указателями. Косвенная адресация.
- •14. Ссылки (пример)
- •15. Статические числовые одномерные
- •16. Статические числовые двумерные массивы.
- •17. Динамическая память.
- •18. Выделение памяти под динамический одномерный и двумерный массив.
- •19. Алгоритм удаления и добавления данных в массив.
- •20. Глобальные, локальные, статические, внешние переменные.
- •21. Классы памяти.
- •22. Формальные и фактические параметры.
- •23. Функции.
- •24. Виды передачи параметров в функцию.
- •25.Функции и массивы
- •26. Функции с переменным числом параметров.
- •27. Шаблоны функции.
- •28.Рекурсии. Фреймы.
- •29. Функция Main()
- •30. Стеки.
- •31. Очереди.
- •33. Строки, как массив символов.
- •34. Функции ввода строковых переменных.
- •35.Основные функции обработки строковых переменных.
- •37. Функции преобразования типов.
- •38. Строки типа string.
- •40. Функции работы с памятью. Memcmp - сравнивает две области памяти
- •41. Структуры
- •42. Вложенные структуры.
- •43. Объединения (union)
- •44.Передача переменных определенных пользователем в функцию.
- •50. Функция определения конца файла.
- •51. Файловый поток.
- •52. Функции tellg и ftell
- •53. Установка файлового указателя
- •55. Обработка текстовых файлов.
- •56. Бинарный файл.
17. Динамическая память.
Различают два типа памяти: статическую и динамическую. В статической памяти размещаются локальные и глобальные данные при их описании в функциях. Для временного хранения данных в памяти ЭВМ используется динамическая память, или heap. Размер этой памяти ограничен, и запрос на динамическое выделение памяти может быть выполнен далеко не всегда.
В С++ для выделения памяти можно также использовать встроенные операторы new и delete.
Оператор new имеет один операнд. Оператор имеет две формы записи:
[::] new [(список_аргументов)] имя_типа [(инициализирующее_значение)]
[::] new [(список_аргументов)] (имя_типа) [(инициализирующее_значение)]
В простейшем виде оператор new можно записать:
new имя_типа или new (имя_типа)
Оператор new возвращает указатель на объект типа имя_типа, для которого выполняется выделение памяти. Например:char *str; // str – указатель на объект типа char
str=new char; // выделение памяти под объект типа char
str=new (char);
Если память не может быть выделена, оператор new возвращает значение NULL.
Оператор new позволяет выделять память под массивы. Он возвращает указатель на первый элемент массива в квадратных скобках. Например:
int *n; // n – указатель на целое
n=new int[20]; // выделение памяти для массива
При выделении памяти под объект его значение будет неопределенным. Однако объекту можно присвоить начальное значение.
int *a = new int (10234);
Использование знака :: перед оператором new указывает на вызов глобальной версии оператора new. Оператор new вызывает функцию operator new(). Аргумент имя_типа используется для автоматического вычисления размера памяти sizeof(имя_типа), то есть инструкция типа new имя_типа приводит к вызову функции:
operator new(sizeof(имя_типа));
Далее, в подразделе «Перегрузка операторов», будет рассмотрен случай использования доопределенного оператора new для некоторого класса. Доопределение оператора new позволяет расширить возможности выделения памяти для объектов (их компонент) данного класса.
Создание объекта с помощью операции new вызывает также выполнение конструктора для этого объекта. Если в new не указан список инициализации либо он пуст (только скобки), то выполняется конструктор по умолчанию (default), который будет рассмотрен ниже. Если имеется непустой список инициализации, то выполняется тот конструктор, для которого этот список соответствует списку аргументов.
При создании массива выполняется стандартный конструктор для каждого элемента.
Отметим преимущества использования оператора new перед использованием malloc():
- оператор new автоматически вычисляет размер необходимой памяти. Не требуется использование оператора sizeof(). При этом он предотвращает выделение неверного объема памяти;
- оператор new автоматически возвращает указатель требуемого типа (не требуется использование оператора преобразования типа);
- имеется возможность инициализации объекта;
- можно выполнить перегрузку оператора new (delete) глобально или по отношению к тому классу, в котором он используется.
Для разрушения объекта, созданного с помощью оператора new, необходимо использовать в программе оператор delete.
Оператор delete имеет две формы записи:
[::] delete переменная_указатель // для указателя на один элемент
[::] delete [] переменная_указатель // для указателя на массив
Единственный операнд в операторе delete должен быть указателем, возвращаемым оператором new. Если оператор delete применить к указателю, полученному не посредством оператора new, то результат будет непредсказуем.
Использование оператора delete вместо delete[] по отношению к указателю на массив может привести к логическим ошибкам. Таким образом, освобождать память, выделенную для массива, необходимо оператором delete [], а для отдельного элемента - оператором delete.
#include <iostream.h>
class A
{ int i; // компонента-данное класса А
public:
A(){} // конструктор класса А
~A(){} // деструктор класса А};
void main()
{ A *a,*b; // описание указателей на объект класса А
float *c,*d; // описание указателей на элементы типа float
a=new A; // выделение памяти для одного объекта класса А
b=new A[3]; // выделение памяти для массива объектов класса А
c=new float; // выделение памяти для одного элемента типа float
d=new float[4]; // выделение памяти для массива элементов типа float
delete a; // освобождение памяти, занимаемой одним объектом
delete [] b; // освобождение памяти, занимаемой массивом объектов
delete c; // освобождение памяти одного элемента типа float
delete [] d; // освобождение памяти массива элементов типа float}
При удалении объекта оператором delete вначале вызывается деструктор этого объекта, а потом освобождается память. При удалении массива объектов с помощью операции delete[] деструктор вызывается для каждого элемента массива.