Темы лекции
Оперативная память
Адресное пространство
Статическая память
Статическая память
Стек
Стек и переменные «+»
Стек и переменные «–»
Стек и функции
Кадр стека
Стек используется для:
Последовательность действий при работе с динамической памятью
Куча
Куча
Сборка мусора
326.69K
Категория: ПрограммированиеПрограммирование

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

1.

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

2. Темы лекции

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

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

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

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

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

5.

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

6.

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

7.

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

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

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

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


#include <iostream>
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) — часть стека,
сформированный одним вызовом функции.
• Кадр стека – механизм передачи аргументов
и выделения временной памяти с
использованием системного стека
• Во время отладки отладчик позволяет
“проходить” по кадрам стека вызовов,
сформированных на данный момент.
• Кадр стека позволяет реализовать рекурсию

15.

16. Стек используется для:


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

17.

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

18.


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

19.

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

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

21.

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

22.

Динамическая память: выделение
Также можно инициализировать переменную при
создании:
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 <iostream>
Особенно это надо учитывать,
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 не означает, что
эти указатели мы в принципе не сможем
использовать.
• Мы сможем их использовать, если присвоим им адрес
другого объекта:

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

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

31.

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

32.

Автоматическая и статическая память выделяются
единоразово перед запуском программы.
Приложение при необходимости может запросить у
ОС дополнительную память через аллокатор или
напрямую через системный вызов.
Языки сверхвысокого уровня используют
динамическую память как основную: создают все или
почти все объекты в динамической памяти, а на
стеке или в статической памяти держат указатели на
эти объекты.
English     Русский Правила