49 lines
3.5 KiB
Markdown
49 lines
3.5 KiB
Markdown
# mem (Memory Wrappers с отслеживанием утечек)
|
||
|
||
## 1. Назначение
|
||
|
||
Обёртки над стандартными `malloc`/`calloc`/`realloc`/`free`/`strdup` с детекцией:
|
||
- **Buffer overflow/underflow** — каждый блок окружён канарейками (`0xDEADBEEF`) и padding-областями, которые проверяются при `u_free` и `u_realloc`. При повреждении — подробный дамп блока и аварийное завершение.
|
||
- **Double free** — двусвязный список всех живых аллокаций; повторное освобождение детектируется по отсутствию блока в списке.
|
||
- **Утечки памяти** — `u_report_unfreed_blocks()` при завершении выводит все незакрытые блоки с местом аллокации (`файл:строка`), размером и hex-дампом данных.
|
||
|
||
Функции потокобезопасны (мьютекс/критическая секция).
|
||
|
||
## 2. Как пользоваться
|
||
|
||
```c
|
||
#include "mem.h"
|
||
|
||
// Вместо malloc/calloc/realloc/free/strdup используй соответствующие макросы:
|
||
void* buf = u_malloc(data_size);
|
||
char* str = u_strdup("hello");
|
||
buf = u_realloc(buf, new_size);
|
||
u_free(buf);
|
||
u_free(str);
|
||
|
||
// В конце main (перед return) — отчёт о незакрытых блоках:
|
||
u_report_unfreed_blocks();
|
||
|
||
// Текущее число живых аллокаций (для диагностики):
|
||
size_t count = u_get_allocated_count();
|
||
```
|
||
|
||
**Важно:**
|
||
- Макросы (`u_malloc`, `u_calloc`, `u_free`, и т.д.) автоматически подставляют `__FILE__:__LINE__` через `LOCATION` — это нужно для диагностики утечек и повреждений. Напрямую вызывай `_impl`-функции только если нужно явно передать location.
|
||
- `u_realloc(NULL, size)` эквивалентен `u_malloc(size)`, `u_realloc(ptr, 0)` эквивалентен `u_free(ptr)`.
|
||
- Потокобезопасность гарантирована, но аллокации с метаданными заметно дороже обычного `malloc` — используй `memory_pool` для hot-path объектов.
|
||
- При обнаружении повреждения (overflow/underflow/double-free) программа завершается через `exit(EXIT_FAILURE)` после вывода отладочной информации.
|
||
|
||
## 3. API
|
||
|
||
| Функция/макрос | Описание |
|
||
|---|---|
|
||
| `u_malloc(size)` | Аналог `malloc` с boundary check и трекингом |
|
||
| `u_calloc(nmemb, size)` | Аналог `calloc` (выделяет + обнуляет) |
|
||
| `u_realloc(ptr, size)` | Аналог `realloc`, с проверкой целостности старого блока |
|
||
| `u_free(ptr)` | Освобождение с проверкой canary, double-free и удалением из списка |
|
||
| `u_strdup(s)` | Аналог `strdup` через u_malloc |
|
||
| `u_report_unfreed_blocks()` | Выводит все незакрытые блоки с дампом; вызывается при shutdown |
|
||
| `u_get_allocated_count()` | Возвращает количество живых аллокаций |
|
||
| `u_check(ptr, text, location)` | Ручная проверка целостности блока (canary + padding) |
|