Виды памяти для АСУб и ЭВМб. Тема 4-1

Содержание

Слайд 2

Темы лекции Типы памяти: статическая, автоматическая, динамическая Указатели и ссылки Умные

Темы лекции

Типы памяти: статическая, автоматическая, динамическая
Указатели и ссылки
Умные указатели в С++
Динамические

массивы
Сравнение динамических и статических массивов
Слайд 3

Оперативная память С точки зрения разработчика оперативная память – упорядоченная последовательность

Оперативная память

С точки зрения разработчика
оперативная память – упорядоченная последовательность ячеек

— байт, предназначенных для размещения данных, которыми оперирует программа во время своего выполнения.
Упорядоченность означает, что каждый элемент последовательности (каждая ячейка памяти) имеет свой порядковый номер.
Этот порядковый номер называют адресом ячейки памяти — адресом байта.
Непрерывный диапазон ячеек, доступный для адресации в конкретной операционной системе, называют адресным пространством
Слайд 4

Адресное пространство Общее количество доступных для адресации ячеек памяти определяется разрядностью

Адресное пространство

Общее количество доступных для адресации ячеек памяти определяется разрядностью операционной

системы, более точно — разрядностью типа данных, используемого в конкретной операционной системе для хранения номера ячейки
Слайд 5

Статическая память — это область памяти, выделяемая при запуске программы до

Статическая память — это область памяти, выделяемая при запуске программы до

вызова главной функции (main) из свободной оперативной памяти для размещения глобальных и статических данных программы.
Автоматическая память — это область памяти, резервируемая при запуске программы до вызова главной функции (main) из свободной оперативной памяти и используемый в дальнейшем для размещения локальных данных.
Динамическая память — это совокупность блоков памяти, выделяемых из доступной свободной оперативной памяти непосредственно во время выполнения программы под размещение конкретных данных
Слайд 6

Автоматическая Динамическая Статическая память память память Направления роста памяти Код программы около нуля

Автоматическая

Динамическая

Статическая
память

память

память

Направления роста памяти

Код программы около нуля

Слайд 7

Статическая память — это область памяти, выделяемая при запуске программы до

Статическая память — это область памяти, выделяемая при запуске программы до

вызова главной функции (main) из свободной оперативной памяти для размещения глобальных и статических данных программы.
Глобальная переменная — переменная, определённая вне функций и доступная из разных функций.
Локальная переменная — переменная, определённая внутри блока кода, в т.ч. функции.
Переменная, определённый с использованием ключевого слова static, называют статическим.
Всё, что сказано про переменные, относится и к константам
Слайд 8

Статическая память Память под статические переменные распределяется компилятором и выделяется при

Статическая память

Память под статические переменные распределяется компилятором и выделяется при запуске

программы, а освобождается при завершении программы
Все глобальные переменные — статические
Для определения статической локальной переменной используется ключевое слово static
Слайд 9

Статическая память #include using namespace std; int x = -1;//глобальная void

Статическая память

#include
using namespace std;
int x = -1;//глобальная
void func(int x);// в

прототипе
int main()
{
setlocale(LC_ALL, "Russian");
int x = -100;
func(100);
func(200);
cout << "из main: " << x << endl;
cout << "глобально: " << ::x << endl;
return 0;
}
void func(int x)// в определении
{
//int x;
cout << "входной параметр из func: " << x << endl;
{
static int x;//инициализация
cout << "в фиктивном блоке из func и статичная : " << x++ << endl;
for (int x = 10; x < 13; x++)//в блоке
{
cout << "в блоке оператора " << x << endl;
}
}
}
Слайд 10

Стек Автоматическая область памяти организована в форме стек Стек поддерживается аппаратно

Стек

Автоматическая область памяти организована в форме стек
Стек поддерживается аппаратно центральным процессором
Слово

“стек” (stack) можно перевести как “стопка”. Объекты добавляются на стек сверху и снимаются потом в обратном порядке.

Стек можно представить в виде трубки с подпружиненым дном, расположеной вертикально.
Верхний конец трубки открыт, в него можно добавлять, или, как говорят, заталкивать элементы

Слайд 11

Стек и переменные «+» Каждый раз, когда функция объявляет новую переменную,

Стек и переменные «+»

Каждый раз, когда функция объявляет новую переменную, она

добавляется в стек, а когда эта переменная пропадает из области действия (например, когда функция заканчивается), она автоматически удаляется из стека.
Из-за такой природы стека управление памятью оказывается весьма логичным и простым для выполнения на ЦП;
Это приводит к высокой скорости, в особенности потому, что время цикла обновления байта стека очень мало, т.е. этот байт скорее всего привязан к кэшу процессора.
Слайд 12

Стек и переменные «–» Тем не менее, у такой строгой формы

Стек и переменные «–»

Тем не менее, у такой строгой формы управления

есть и недостатки. Размер стека — это фиксированная величина, и превышение лимита выделенной на стеке памяти приведёт к переполнению стека.
Размер задаётся в начале выполнения программы, и у каждой переменной есть максимальный размер, зависящий от типа данных.
Это позволяет ограничивать размер некоторых переменных (например, целочисленных), и вынуждает заранее объявлять размер более сложных типов данных (например, массивов), поскольку стек не позволит им изменить его.
Переменные, расположенные на стеке, всегда являются локальными.
Автоматические переменные встроенных типов по умолчанию не инициализируются, для инициализации необходимо присвоить начальное значение явно.
Слайд 13

Стек и функции Одно из главных назначений стека — поддержка вызовов

Стек и функции

Одно из главных назначений стека — поддержка вызовов функций

(подпрограмм).
При вызове функций надо сохранить адрес возврата, чтобы подпрограмма могла по окончанию своей работы вернуть управление вызвавшей ее программе.
Слайд 14

Кадр стека Кадр стека (stack frame) — часть стека, сформированный одним

Кадр стека

Кадр стека (stack frame) — часть стека, сформированный одним вызовом функции.


Кадр стека – механизм передачи аргументов и выделения временной памяти с использованием системного стека
Во время отладки отладчик позволяет “проходить” по кадрам стека вызовов, сформированных на данный момент. 
Кадр стека позволяет реализовать рекурсию
Слайд 15

Слайд 16

Стек используется для: Выделения и освобождения памяти под локальные переменные Вызова

Стек используется для:
Выделения и освобождения памяти под локальные переменные
Вызова функции call

name
поместить в стек адрес команды, следующей за командой call
передать управление по адресу метки name
Возврата из функции
извлечь из стека адрес возврата address
передать управление на адрес address
Слайд 17

Динамическая память Динамическая память — это совокупность блоков памяти, выделяемых из

Динамическая память

Динамическая память — это совокупность блоков памяти, выделяемых из

доступной свободной оперативной памяти непосредственно во время выполнения программы под размещение конкретных данных
Максимальный размер динамической памяти зависит от многих факторов: среди них ОС, процессор, аппаратная архитектура в целом, не говоря уже о самом очевидном — максимальном размере ОЗУ у конкретного устройства
Продолжительность жизни переменных, объявленных динамически, не зависит от того, где они созданы. Динамические объекты существуют, пока не будут удалены явным образом.
Динамические объекты C++ размещаются в динамической памяти (free store). В других языках программирования и в С используется понятие КУЧА
Слайд 18

Аллокатор (распределитель памяти) — это часть программы, которая запрашивает память большими

Аллокатор (распределитель памяти) — это часть программы, которая запрашивает память большими

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

Динамическая память: аллокатор

Слайд 19

Динамическая память Для управления динамическими переменными FREE STORE применяются операции new

Динамическая память

Для управления динамическими переменными FREE STORE применяются операции new и

delete.
Операция new выделяет место в динамической памяти для переменной и возвращает указатель на эту переменную.
Операция delete получает указатель на динамическую переменную и удаляет его из памяти.
Для управления динамическими переменными в КУЧЕ применяются функции malloc и free
Слайд 20

Последовательность действий при работе с динамической памятью

Последовательность действий при работе с динамической памятью

Слайд 21

Динамическая память: выделение Создание динамического объекта: int *ptr = new int;

Динамическая память: выделение
Создание динамического объекта:
int *ptr = new int;
Операция new

создает новую переменную типа int в динамической памяти и возвращает указатель на него. Значение этой переменной не определено.
Слайд 22

Также можно инициализировать переменную при создании: int *p1 = new int();

Также можно инициализировать переменную при создании:
int *p1 = new int(); //

значение по умолчанию - 0
std::cout << "p1: " << *p1 << std::endl; // 0
int *p2 = new int(12);
std::cout << "p2: " << *p2 << std::endl; // 12

Динамическая память: выделение

Слайд 23

При запросе памяти из операционной системы в редких случаях она может

При запросе памяти из операционной системы в редких случаях она может

быть не выделена
По умолчанию, если оператор new не сработал, память не выделилась, то генерируется исключение bad_alloc
Проверка запросов на выделение памяти
int *value = new (std::nothrow) int; // запрос на выделение динамической памяти для целочисленного значения
if (!value) // обрабатываем случай, когда new возвращает null (т.е. память не выделяется)
{
// Обработка этого случая
std::cout << "Could not allocate memory";
}

Динамическая память: выделение

Слайд 24

Динамические переменные будут существовать пока не будут явным образом удалены. После

Динамические переменные будут существовать пока не будут явным образом удалены.
После

завершения использования динамических переменных следует освободить их память с помощью оператора delete:
int *p1 = new int(12);
std::cout << "p1: " << *p1 << std::endl; // 0
delete p1;

Освобождение памяти

Динамическая память: освобождение

Слайд 25

#include int* createPtr(int value) { int *ptr = new int(value); return

#include
int* createPtr(int value)
{
int *ptr = new int(value);
return ptr;
}
void

usePtr()
{
int *p1 = createPtr(10);
std::cout << *p1 << std::endl; // 10
delete p1; // переменную надо освободить
}
int main()
{
usePtr();
return 0;
}

Особенно это надо учитывать, если динамическая переменная создается в одной части кода, а используется в другой.

Динамическая память: освобождение

Слайд 26

Куча Куча — это хранилище памяти, также расположенное в ОЗУ, которое

Куча

Куча — это хранилище памяти, также расположенное в ОЗУ, которое допускает

динамическое выделение памяти и не работает по принципу стека: это просто склад для ваших переменных.
Когда вы выделяете в куче участок памяти для хранения переменной, к ней можно обратиться не только в потоке, но и во всем приложении.
По завершении приложения все выделенные участки памяти освобождаются.
Размер кучи задаётся при запуске приложения, но, в отличие от стека, он ограничен лишь физически, и это позволяет создавать динамические переменные.
Слайд 27

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

Куча

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

чьи значения являются адресами других переменных.
Создавая указатель, вы указываете на местоположение памяти в куче, что задаёт начальное значение переменной и говорит программе, где получить доступ к этому значению. Из-за динамической природы кучи ЦП не принимает участия в контроле над ней; в языках без сборщика мусора (C, C++) разработчику нужно вручную освобождать участки памяти, которые больше не нужны. Если этого не делать, могут возникнуть утечки и фрагментация памяти, что существенно замедлит работу кучи.
В сравнении со стеком, куча работает медленнее, поскольку переменные разбросаны по памяти, а не сидят на верхушке стека. Некорректное управление памятью в куче приводит к замедлению её работы; тем не менее, это не уменьшает её важности — если вам нужно работать с динамическими или глобальными переменными, пользуйтесь кучей.
Слайд 28

Использование объекта по указателю после его удаления или повторное применение оператора

Использование объекта по указателю после его удаления или повторное применение оператора

delete к указателю могут привести к непредсказуемым результатам:

Поэтому следует удалять объект только один раз.
Возможно, когда на один и тот же динамический объект указывают сразу несколько указателей. Если оператор delete применен к одному из указателей, то память объекта освобождается, и по второму указателю этот объект мы использовать уже не сможем.

Динамическая память: освобождение

Слайд 29

Если же после этого ко второму указателю применить оператор delete, то

Если же после этого ко второму указателю применить оператор delete, то

динамическая память может быть нарушена.
В то же время недопустимость указателей после применения к ним оператора delete не означает, что эти указатели мы в принципе не сможем использовать.
Мы сможем их использовать, если присвоим им адрес другого объекта:

Динамическая память: освобождение

Слайд 30

Сборка мусора Сборка мусора (garbage collection) — одна из форм автоматического

Сборка мусора

Сборка мусора (garbage collection)  — одна из форм автоматического управления памятью.
Сборщик

мусора управляет выделением и освобождением памяти для приложения. Следовательно, разработчикам не нужно писать код для выполнения задач по управлению памятью.
Автоматическое управление памятью позволяет устранить распространенные проблемы, которые связаны с утечкой памяти из-за того, что объект не был освобожден, или попыткой доступа к памяти для объекта, который был освобожден.
Слайд 31

Выделить память под переменную; Инициализировать выделенную память некоторым начальным значением; Предоставить

Выделить память под переменную;
Инициализировать выделенную память некоторым начальным значением;
Предоставить программисту возможность

использования этой памяти;
Как только память перестает использоваться, необходимо ее освободить(возможно, предварительно очистив)
Наконец, необходимо обеспечить возможность последующего повторного использования освобожденной памяти

Алгоритм сборки мусора