-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy path12_memory.cpp
More file actions
74 lines (52 loc) · 4.02 KB
/
12_memory.cpp
File metadata and controls
74 lines (52 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Исходный код программы на С++.
int main() { // область видимости функции
// 1. Автоматическое управление памятью на стеке.
// До этого момента мы работали с автоматическим выделением и освобождением памяти.
// Автоматическое управление памятью производится в рамках областей видимости (scopes).
{ // область видимости
// Автоматически выделяется память под переменные.
int var = 0;
int arr[2] = {};
} // область видимости закрылась
// Здесь, у нас уже нет переменной 'var' и массива 'arr'.
// Участки памяти, выделенные под переменные, свободны и могут быть повторно использованы.
{
// Память выделяется из специального резервуара - стека.
// Стек имеет довольно ограниченный размер - что будет, если раскомментировать код ниже?
// int arr[1000000];
}
// 2. Ручное управление памятью на куче (heap).
// Проблема нехватки памяти на стеке решается при помощи динамической памяти.
// Динамическое выделение памяти - способ запроса памяти из ОС.
// Память выделяется из объемного резервуара - кучи (heap).
{
// Запросим выделение памяти для хранения целочисленного типа int.
// Оператор new возвращает указатель, который содержит адрес выделенной памяти.
int *pointer = new int; // по адресу хранится "мусор"
*pointer = 1; // устанавливаем значение участка памяти по указателю
// При выходе из области видимости указатель автоматически "удалится" из памяти.
// НО, участок памяти, на который ссылается указатель - НЕТ.
delete pointer; // вручную высвобождаем выделенную память при помощи оператора delete
pointer = nullptr; // "обнуление указателя", является хорошей практикой
// Рубрика "что будет, если":
// - повторно высвободим участок памяти, на который ссылает pointer
// - не обнулить указатель после высвобождения памяти
}
// 3. Утечка памяти.
{
// выделение памяти под int, инициализация значением 0, сохранение адреса в указатель
int *pointer = new int{0};
// ой, забыли высвободить память...
}
// Что произошло?
// 1. Программа зарезервировала у ОС участок памяти и не высвободила его.
// 2. ОС думает, что этот участок памяти занят и не трогает его.
// 3. Участок памяти высвободится только при завершении программы.
return 0;
}
/*
* Задания:
* 1. Что занимается автоматическим выделением памяти: ОС, компилятор?
* 2. Чем страшна утечка памяти? Приведите примеры.
* 3. Управляют ли вручную памятью в современном C++?
*/