Підтікання пам’яті
Що таке підтікання пам’яті? Це довготривалий процес взаємодії коду програми з машиною в наслідок якого об’єм вільної оперативної пам’яті зменшується.
Бій за кожен байт
В одному проекті у якому мені довелося взяти участь я натрапив на такий код. Для мене було дивно та дико бачити це у проекті які писали “професійні” кодери. Саркастично бо мій досвід програмування незрівнянно малий у порівнянні з їх досвідом.
Я рішив дослідити як поводить себе програма на однокристальниках при підтіканні пам’яті.
“Страшний” код я не можу показати через КопіПравий та “Секретність” тому рішив змоделювати поведінку коду
Код
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
| /************************************************************
* Моделювання MEMORY LEAK на однокристальних комп'ютерах. *
* *
* Використовуємо Arduino IDE та кристал ATmega2560 *
************************************************************/
void setup() {
/************************************************************
* Нам потрібно стежити за поведінкою коду on real time *
* тому запускаємо сесію звязку з ПК по серійному каналу *
************************************************************/
Serial.begin(9600);
}
/************************************************************
* Починаємо робочий цикл *
***********************************************************/
void loop() {
/************************************************************
* В головному циклі будемо займати комірку розміром у один *
* байт. *
************************************************************/
char* pointer = new char;
/************************************************************
* Оператор new повертає адресу пам'яті яку нам виділено. *
* Якщо пам'яті нема - повертає нуль. У мові C більш відоме *
* як NULL, а в новому стандарті C++ nullptr. *
* *
* Arduino використовує C++. В якому ще не було завезено *
* оператора nullptr тому вказівних будемо порівнювати з *
* NULL. *
* *
* Перевіряти вказівник можна двома способами *
* if( !pointer ) команди; *
* або *
* if( pointer==NULL ) команди; *
************************************************************/
/************************************************************
* Будемо перевіряти чи в нас закінчилась пам'ять *
***********************************************************/
if (!pointer) {
/************************************************************
* Ці інструкції процесор виконає коли пам'ять закінсться *
* Що ми зробимо коли пам'ять закінчиться? *
* Повідомимо про кінець пам'яті *
************************************************************/
Serial.println("MEMORY_LEAK");
/************************************************************
* та залипаємо у вічному циклі *
************************************************************/
for (;;);
};
/************************************************************
* у виділену пам'ять ми можемо записати якесь число, але *
* подивимось як виглядає не ініціалізована пам'ять.Зазвичай*
* там не нуль і не порожнеча, а сміття. подивимось що там. *
* *
* Виведемо у форматі Адреса і hex вміст. *
************************************************************/
Serial.print((int)pointer);
Serial.print("\t");
Serial.println(*pointer, HEX);
/***********************************************************
* В serial monitor виводяться адреси починаючи з 714. *
* Думаю що від 0 до 714 займає бутлоатер *
* Зупиняється вивід на адресі 8562. Що відповідає розміру *
* оперативної пам'яті ATmega2560 *
* 8Kbytes Internal SRAM *
**********************************************************/
/***********************************************************
* А тепер перекриємо витякання пам'яті. Розкоментуйте *
* наступний рядок *
***********************************************************/
// #define MEMORY_LEAK_OFF
#ifdef MEMORY_LEAK_OFF
/***********************************************************
* Кожного разу коли коритуємось оператором new потрібно *
* користуватись оператором delete *
* *
* Вони завжди ходять в парі. *
* *
* У коді на кожен new бути свій delete *
* і на кожен delete свій new. *
* *
* Зайве видалення призводить до іншої помилки про яку я *
* постараюсь написати. *
***********************************************************/
delete pointer;
/***********************************************************
* Тепер грузимо код на кристал і спостерігаємо що адреса *
* не змінюється.Ми бачимо першу вільну комірку оперативної*
* пам'яті не зайняту бутлоадером *
***********************************************************/
#endif
}
|
Замість висновку
Кожного разу коли на себе берете виділення пам’яті слідкуйте щоб її вчасно звільніти