Consolidate memory ownership and allocation documentation in header
This commit is contained in:
1 parent
3944459c29
commit
e403a2f689
2 files changed
+16
-49
No files matched your search
@@ -2,7 +2,10 @@
|
||||
* mem — выделение памяти с защитными полями, местом аллокации и учётом живых блоков.
|
||||
* Использовать u_malloc/u_calloc/u_realloc/u_strdup и парный u_free; обычный free к этим блокам неприменим.
|
||||
* Макросы передают LOCATION автоматически. OOM возвращает NULL; обнаруженное повреждение завершает процесс.
|
||||
* realloc при ошибке сохраняет старый блок, при size=0 освобождает его.
|
||||
* realloc живого блока при ошибке сохраняет его, при size=0 освобождает; NULL обрабатывается как malloc.
|
||||
* Размеры аргументов _impl — uint32_t; до вызова проверить, что исходные size_t помещаются в этот диапазон.
|
||||
* Список аллокаций защищён мьютексом; доступ к одному блоку и чтение счётчика согласует вызывающий.
|
||||
* Защитные поля проверяются для живых блоков; обращение к уже освобождённому/чужому указателю недопустимо.
|
||||
* Отчёт u_report_unfreed_blocks вызывать после остановки потоков, меняющих список аллокаций.
|
||||
*/
|
||||
#ifndef MEM_H
|
||||
@@ -15,18 +18,30 @@ extern "C" {
|
||||
#define XSTR(s) STR(s)
|
||||
#define STR(s) #s
|
||||
#define LOCATION __FILE__ ":" XSTR(__LINE__)
|
||||
// Проверяет canary/padding живого блока; text/location — строки диагностики. NULL ptr допустим.
|
||||
// Обнаруженное повреждение логируется в SYS и завершает процесс через exit(EXIT_FAILURE).
|
||||
void u_check(void* ptr, const char* text, const char* location);
|
||||
#define u_malloc(size) u_malloc_impl(size, LOCATION)
|
||||
#define u_calloc(nmemb, size) u_calloc_impl(nmemb, size, LOCATION)
|
||||
#define u_realloc(ptr, size) u_realloc_impl(ptr, size, LOCATION)
|
||||
#define u_free(ptr) u_free_impl(ptr, LOCATION)
|
||||
#define u_strdup(s) u_strdup_impl(s, LOCATION)
|
||||
// Выделяет size байт с метаданными; NULL при OOM/переполнении полного размера. size=0 тоже создаёт учтённый блок.
|
||||
// location — обязательная строка места вызова, копируется в метаданные; payload не обнуляется.
|
||||
void* u_malloc_impl(uint32_t size, const char* location);
|
||||
// Выделяет и обнуляет nmemb*size байт; NULL при произведении > UINT32_MAX или ошибке malloc.
|
||||
void* u_calloc_impl(uint32_t nmemb, uint32_t size, const char* location);
|
||||
// NULL ptr → malloc(size), включая size=0. Для живого ptr: size=0 → free и NULL;
|
||||
// иначе новый блок с min(старый размер, size) байтами данных. При OOM возвращает NULL, старый блок сохранён.
|
||||
// Результат сохранять временно: tmp = u_realloc(ptr, size); if (tmp) ptr = tmp; (при size > 0).
|
||||
void* u_realloc_impl(void* ptr, uint32_t size, const char* location);
|
||||
// Проверяет и освобождает живой блок из этих обёрток; NULL допустим. Обычный free к нему неприменим.
|
||||
void u_free_impl(void* ptr, const char* location);
|
||||
// Копирует ASCIIZ-строку (strlen(s)+1 должно помещаться в uint32_t); NULL при NULL s/OOM. Освобождать u_free.
|
||||
char* u_strdup_impl(const char* s, const char* location);
|
||||
// После остановки изменяющих список потоков: статистика и дампы живых блоков; сами блоки не освобождает.
|
||||
void u_report_unfreed_blocks(void);
|
||||
// Число живых блоков, чтение без блокировки; параллельные аллокации/освобождения нужно исключить извне.
|
||||
size_t u_get_allocated_count(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# 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) |
|
||||
Reference in new issue
Block a user