TGViewer
this->notes. this->notes. @thisnotes · 4.53K subscribers
Post #186 1.36K
#cpp

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

Заведём структурку, в которую будем складывать необходимую информацию:

struct AllocationInfo {
const char* function;
unsigned int line;
unsigned long count;
unsigned long bytes;
AllocationInfo* next;
};


Это базовая нода листа, в которой будем хранить всю необходимую информацию об аллокации. Ну и заведём голову листа:

static AllocationInfo root;

Теперь напишем макрос, который будет служить базой для функции аллокации:

#define MYALLOCATE(n, name) \
[name_data = name] (size_t bts) { \
static AllocationInfo here; \
static bool firstCall = [name_data]() { \
/*first call, initialize the struct*/ \
here.function = name_data; \
here.line = __LINE__; \
here.next = root.next; \
root.next = &here; \
return true; \
}(); \
/* Cool, now deposit info about calls */ \
++here.count; \
here.bytes += (bts); \
return malloc(bts); \
}(n)


Создаём новую ноду листа, которую инициализируем при первом появлении в строчке, после чего обновляем инфу если надо. Ну и макрос-обёртка:

#define ALLOC(n) MYALLOCATE(n, __PRETTY_FUNCTION__)

Теперь везде где хочется выделять память теперь будем использовать макрос ALLOC. И в конце можем обойти лист, получим всю необходимую информацию:

auto p = &root;
p = p->next;
while (p) {
std::cout << "Func: " << p->function << std::endl;
std::cout << "Line: " << p->line << std::endl;
std::cout << "Times: " << p->count << std::endl;
std::cout << "Bytes: " << p->bytes << std::endl;
p = p->next;
}


Демо. И можем увидеть какие-то такие результаты:

Func: int main()
Line: 46
Times: 1
Bytes: 128

Func: void some_func(size_t)
Line: 36
Times: 2
Bytes: 48

Func: int main()
Line: 40
Times: 1
Bytes: 8


Видим, что в main в строке 46 за один раз было выделено 128 байт; в some_func в строке 36 за два раза 48 байт и в main в строке 40 за раз 8 байт.

Количество раз для каждой строки мы считаем т.к. используются статические переменные для нод листа, из-за чего при нескольких обращениях ноды переиспользуются. Можно складывать сюда таймпоинты выделений памяти или что угодно ещё. Прикона короч.

И самый сок, что весь лист у вас static, т.е. у нас нет динамических аллокаций на него. Только те, которые лежат под вызовом ALLOC. Т.е. информация категорически точная.
Мне когда-то голову взорвало.

Можно немножко зарефакторить код, юзая std::source_location. Оставим как упражнение пытливому читателю.

===================================
Что-то в последнее время начала ощущаться усталость от 2.5 лет нехождения в отпуск. Потому дольше обычного не было постов (ну и ещё из-за запойного просмотра Доктора Хауса). Но, думаю, скоро получится отдохнуть и всё вернётся в нормальный ритм.
  • 👍 15
More from @thisnotes
  1. Sep 17, 2026#common Сидите вы себе спокойно, разрабатываете поиск каких-нибудь объектов. Может это тов…
  2. Sep 9, 2026#cpp #books Да, книга 2001ого года. Мы ровесники. И да, в ней в основном обсуждаются какие…
  3. Sep 2, 2026#perf Попробовал собрать в кучку (кажется, немного сумбурно всё же) мысли по двум моментам…
  4. Aug 31, 2026Давайте новый тег заведём: #perf Во-первых, надо понять, что я вообще понимаю под перфом,…
  5. Aug 27, 2026#common Мы часто делаем системы, которые обладают какими-то ограничениями. Ограничения наш…
  6. Aug 24, 2026#list 0. [talk] Achieving Peak Performance for Matrix Multiplication in C++. Aliaksei Sala…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →