Не обещаю, что эта рубрика станет постоянной. Во-первых, я существо ленивое, а, во-вторых, подготовить хороший, качественный говнокод – намного сложнее, чем написать такого же качества обычную, нормальную программу.
Итак, приступим!
В этих ваших Интернетах постоянно вылазят какие-то фрики и утверждают, что якобы оператор new
ни в коем случае нельзя использовать без парного ему delete
! Якобы, от этого неминуемо произойдёт утечка памяти и со временем память может просто закончиться. Так оно и было, но сейчас это устарело! Память бесконечна, если использовать новую технологию, которая пока добавлена экспериментально (и потому не особо документирована), но «нормальные пацаны» в курсе!
Как это сделать? Как получить доступ к бесконечной памяти? Нужно выполнить несколько простых шагов:
- определить тип данных с фиксированным названием
_endless_memory_type_
. Это может быть любой тип – память из бесконечного пула будет выделяться блоками этого типа; - определить блок данных типа
_endless_memory_type_
с фиксированным названием_endless_memory_
– это «образец» блоки из бесконечной памяти будут создаваться по образу и подобию этого образца; - зарегистрировать определённые в п.п.1 и 2 тип и образец в системе;
Всё! Теперь можно сколько угодно раз запрашивать блоки памяти типа _endless_memory_type_
и, если при каждом запросе указывать созданный образец, то память будет выделяться столько раз, сколько запросим. Никакого исчерпания памяти и никаких delete
! Всё, что нужно – не забывать указывать образец при запросе!
Ниже приведён пример кода, где всё это делается и достаточно подробно прокомментировано. Код для Arduino Uno. IDE у меня 2.2.1. В более поздних версиях работает точно. В ранних тоже работает, но только в тех, где используется достаточно новый компилятор (в который эту недокументированную фичу уже добавили). Кстати, не вижу причин, почему бы этому не работать на RSP или ARM, лишь бы компилятор свежий был.
Запускайте, смотрите
/////////////////////////////////////////////////
//
// Arduino UNO
// IDE - проверялось в 2.2.1, но подойдёт любая более или менее современная
//
#include <new.h>
// Размер буфера - 1 килобайт
static constexpr size_t BufferLenght = 1024;
//
// создание типа блока бесконечной памяти
//
typedef uint8_t _endless_memory_type_ [BufferLenght];
//
// Шаблон блока
//
_endless_memory_type_ _endless_memory_;
//
// регистрация созданных типа и шаблона
//
#pragma push_macro("_endless_memory_type_ _endless_memory_")
//
// Размер типа _endless_memory_type_ в байтах
//
static constexpr size_t sizeEMT = sizeof(_endless_memory_type_);
//
// Запрос блока памяти типа _endless_memory_type_ по шаблону _endless_memory_
// (никаких delete !!!)
//
void bottomLess(void) {
//
// Выделим память
//
uint8_t * newBuff = new (_endless_memory_) _endless_memory_type_;
//
// Проверим, выделилась ли
//
if (! newBuff) { // Если память не дали
Serial.println("It sucks! Memory exhausted!");
return;
}
//
// ПРОВЕРКА, всё ли нормально с выделенной памятью
//
// Для этого возьмём случайное байтовое значение
//
const uint8_t content = random(256);
Serial.print("Content: ");
Serial.print(content);
//
// и заполним выделенный буфер этим значением
//
memset(newBuff, content, sizeEMT);
//
// Проверим как заполнилось
// Для этого напечатаем 8 случайных байтов из буфера
// Все они должны быть равны тому, чем заполняли
//
Serial.print("; Random bytes:");
for (uint8_t i = 0; i < 8; i++) {
Serial.print(' ');
Serial.print(newBuff[random(sizeEMT)]);
}
Serial.println();
}
void setup(void) {
Serial.begin(9600);
//
// Напечатаем размер блока, который будем запрашивать в байтах
// просто для контроля, сколько на самом деле запрашиваем
//
Serial.print("Size of the _endless_memory_type_ in bytes: ");
Serial.println(sizeEMT);
//
// Выполним 50 запросов блока типа _endless_memory_type_ при помощи new
// При этом никаких delete не делаем.
//
for (uint8_t i = 0; i < 50; bottomLess(), i++);
//
// 50 раз успешно запросили килобайтный буфер.
// Можно продолжать, она и 100 и 1000 раз выделится память бесконечна!
}
void loop(void) {}
а вот и
Результат в мониторе порта
Size of the _endless_memory_type_ in bytes: 1024
Content: 167; Random bytes: 167 167 167 167 167 167 167 167
Content: 77; Random bytes: 77 77 77 77 77 77 77 77
Content: 152; Random bytes: 152 152 152 152 152 152 152 152
Content: 214; Random bytes: 214 214 214 214 214 214 214 214
Content: 243; Random bytes: 243 243 243 243 243 243 243 243
Content: 97; Random bytes: 97 97 97 97 97 97 97 97
Content: 20; Random bytes: 20 20 20 20 20 20 20 20
Content: 72; Random bytes: 72 72 72 72 72 72 72 72
Content: 155; Random bytes: 155 155 155 155 155 155 155 155
Content: 254; Random bytes: 254 254 254 254 254 254 254 254
Content: 108; Random bytes: 108 108 108 108 108 108 108 108
Content: 152; Random bytes: 152 152 152 152 152 152 152 152
Content: 54; Random bytes: 54 54 54 54 54 54 54 54
Content: 15; Random bytes: 15 15 15 15 15 15 15 15
Content: 201; Random bytes: 201 201 201 201 201 201 201 201
Content: 221; Random bytes: 221 221 221 221 221 221 221 221
Content: 0; Random bytes: 0 0 0 0 0 0 0 0
Content: 215; Random bytes: 215 215 215 215 215 215 215 215
Content: 245; Random bytes: 245 245 245 245 245 245 245 245
Content: 2; Random bytes: 2 2 2 2 2 2 2 2
Content: 9; Random bytes: 9 9 9 9 9 9 9 9
Content: 180; Random bytes: 180 180 180 180 180 180 180 180
Content: 215; Random bytes: 215 215 215 215 215 215 215 215
Content: 193; Random bytes: 193 193 193 193 193 193 193 193
Content: 240; Random bytes: 240 240 240 240 240 240 240 240
Content: 127; Random bytes: 127 127 127 127 127 127 127 127
Content: 27; Random bytes: 27 27 27 27 27 27 27 27
Content: 242; Random bytes: 242 242 242 242 242 242 242 242
Content: 232; Random bytes: 232 232 232 232 232 232 232 232
Content: 39; Random bytes: 39 39 39 39 39 39 39 39
Content: 53; Random bytes: 53 53 53 53 53 53 53 53
Content: 30; Random bytes: 30 30 30 30 30 30 30 30
Content: 50; Random bytes: 50 50 50 50 50 50 50 50
Content: 202; Random bytes: 202 202 202 202 202 202 202 202
Content: 202; Random bytes: 202 202 202 202 202 202 202 202
Content: 154; Random bytes: 154 154 154 154 154 154 154 154
Content: 232; Random bytes: 232 232 232 232 232 232 232 232
Content: 56; Random bytes: 56 56 56 56 56 56 56 56
Content: 195; Random bytes: 195 195 195 195 195 195 195 195
Content: 2; Random bytes: 2 2 2 2 2 2 2 2
Content: 115; Random bytes: 115 115 115 115 115 115 115 115
Content: 135; Random bytes: 135 135 135 135 135 135 135 135
Content: 112; Random bytes: 112 112 112 112 112 112 112 112
Content: 107; Random bytes: 107 107 107 107 107 107 107 107
Content: 124; Random bytes: 124 124 124 124 124 124 124 124
Content: 231; Random bytes: 231 231 231 231 231 231 231 231
Content: 50; Random bytes: 50 50 50 50 50 50 50 50
Content: 147; Random bytes: 147 147 147 147 147 147 147 147
Content: 133; Random bytes: 133 133 133 133 133 133 133 133
Content: 23; Random bytes: 23 23 23 23 23 23 23 23
Как видите, в коде мы 50 раз успешно запрашиваем куски памяти по 1 килобайту при помощи new
. Никаких delete
в коде нет. Можно и больше запросить – никто не мешает. Всё отлично работает. А так, между прочим, Вы ещё помните, сколько всего памяти у Uno? То-то!
Как это работает?
Ну, за подробностями к физикам, я лишь слышал, что при работе тактовых генераторов на частотах от 1МГц и выше, вокруг контроллера возникает устойчивое торсионное поле. Оно микромощное, но этой микромощности достаточно для связи с торсионными полями Метавселенной, что позволяет организовать хранение практически неограниченных объёмов данных с мгновенным доступом к ним. Теоретически, конечно, память не бесконечна, её размер ограничен информационной ёмкостью Метавселенной, но это такие величины, что … ну, Вы поняли!
Так это или не так, но оно ведь работает! Вы же сами запускали и видели!
С пятницей, дорогие коллеги!