20260829 Redesign

This commit is contained in:
2026-08-29 00:53:40 +08:00
parent f9345bdc0a
commit bf5fc3bda6
44 changed files with 2941 additions and 1 deletions
+410
View File
@@ -0,0 +1,410 @@
#include <c_Memory.h>
#if C_IS_OS_WINDOWS
#include <malloc.h> /* Windows 下的 _aligned_malloc 需要此头文件 */
#endif
#ifndef NDEBUG
#include <stdio.h>
#endif
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#if defined(C_MEMORY_USE_LOCAL_SYSTEM)
void* c_Memory_Alloc(c_size_t nBytes, const char* file, int line) {
return malloc(nBytes);
}
void* c_Memory_Calloc(c_size_t nCount, c_size_t nBytes, const char* file, int line) {
return calloc(nCount, nBytes);
}
void* c_Memory_Realloc(void* ptr, c_size_t nBytes, const char* file, int line) {
return realloc(ptr, nBytes);
}
void c_Memory_Free(void* ptr, const char* file, int line) {
if (!ptr) return;
free(ptr);
}
void* c_Memory_Aligned_Alloc(c_size_t alignment, c_size_t nBytes, const char* file, int line) {
/* 1. 统一防御边界:凡是申请 0 字节的,全生命周期内统一斩断并返回 NULL */
if (C_UNLIKELY(nBytes == 0)) {
return NULL;
}
/* 2. 硬件级严苛校验:对齐边界必须大于零,且必须是 2 的有限幂 (如 8, 16, 32, 64)
利用经典的位运算 (align & (align - 1)) == 0 进行快速断言 */
if (C_UNLIKELY(alignment == 0 || (alignment & (alignment - 1)) != 0)) {
return NULL;
}
/* 3. 系统级约束规避:对齐边界绝对不能小于当前平台的指针位宽 (32位系统下为4,64位系统下为8) */
if (alignment < sizeof(void*)) {
alignment = sizeof(void*);
}
void* raw_ptr = NULL;
/* ==============================================================================
* 🚀 跨平台多路物理分支隔离分化
* ============================================================================== */
#if C_IS_OS_WINDOWS
/* 无论您本地使用的是 MSVC 还是 MSYS2 MinGW,在 Windows 上均走微软的原生高速对齐堆接口 */
raw_ptr = _aligned_malloc(nBytes, alignment);
#elif C_IS_OS_LINUX || C_IS_OS_FREEBSD || C_IS_OS_MACOS
/* 在标准的类 Unix (POSIX) 谱系下,调用 posix_memalign
注意:它的设计是传入指针的指针,成功时返回 0,失败时返回错误码 */
int result = posix_memalign(&raw_ptr, alignment, nBytes);
if (C_UNLIKELY(result != 0)) {
raw_ptr = NULL; /* 强制拦截,确保失败时指针处于绝对纯净的 NULL 状态 */
}
#else
/* 终极未知平台兜底:普通的 malloc 在 64 位系统下天然具备 16 字节对齐能力,但无法支持更高对齐 */
/* 如果项目未来被移植到某些不支持 posix_memalign 的极端微内核或嵌入式系统,将在此激活降级 */
raw_ptr = malloc(nBytes);
#endif
return raw_ptr;
}
void* c_Memory_Aligned_Calloc(c_size_t alignment, c_size_t num, c_size_t size, const char* file, int line) {
c_size_t total_bytes = num * size;
if (total_bytes == 0) return NULL;
// 直接复用我们写好的跨平台对齐分配器
void* ptr = c_Memory_Aligned_Alloc(alignment, total_bytes, file, line);
if (C_LIKELY(ptr)) {
// 强制物理内存清零,保证安全性
memset(ptr, 0, total_bytes);
}
return ptr;
}
void* c_Memory_Aligned_Realloc(size_t alignment, void* ptr, size_t new_size, const char* file, int line) {
if (!ptr) return c_Memory_Aligned_Alloc(alignment, new_size, file, line);
if (new_size == 0) {
c_Memory_Aligned_Free(ptr, file, line);
return NULL;
}
if (alignment < sizeof(void*)) alignment = sizeof(void*);
void* new_ptr = NULL;
#if C_IS_OS_WINDOWS
new_ptr = _aligned_realloc(ptr, new_size, alignment);
#else
new_ptr = c_Memory_Aligned_Alloc(alignment, new_size, file, line);
if (C_LIKELY(new_ptr)) {
memcpy(new_ptr, ptr, new_size);
c_Memory_Aligned_Free(ptr, file, line);
}
#endif
return new_ptr;
}
void c_Memory_Aligned_Free(void* ptr, const char* file, int line) {
#if C_IS_OS_WINDOWS
/* 🚨 微软大坑警告:Windows 下通过 _aligned_malloc 出来的内存,
必须、绝对、强制使用对应的 _aligned_free 释放!混用普通 free 会直接引发蓝屏或堆破坏崩溃 */
_aligned_free(ptr);
#else
/* 在 POSIX (Linux, macOS, FreeBSD) 下,posix_memalign 出来的地址本质上只是常规堆的延伸,
可以直接且必须使用标准的 free() 进行释放 */
free(ptr);
#endif
}
#else
#if !defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)
C_PACKED_STRUCT_START
typedef struct c_MemoryNode_t {
void* address;
size_t size;
const char* file;
int line;
struct c_MemoryNode_t* next;
} C_PACKED c_MemoryNode_t;
C_PACKED_STRUCT_END
static c_MemoryNode_t* g_tracker_head = NULL;
static size_t g_active_allocations = 0;
static size_t g_total_allocated_bytes = 0;
C_STATIC_FORCE_INLINE
int c_tracker_exists(void* ptr) {
c_MemoryNode_t* curr = g_tracker_head;
while (curr) {
if (curr->address == ptr) return 1;
curr = curr->next;
}
return 0;
}
/* 内部辅助:将分配记录加入追踪器 */
C_STATIC_FORCE_INLINE
void c_tracker_add(void* ptr, size_t size, const char* file, int line) {
if (!ptr) return;
c_MemoryNode_t* node = (c_MemoryNode_t*)malloc(sizeof(c_MemoryNode_t));
if (C_UNLIKELY(!node)) return; /* 防御极端内存耗尽 */
node->address = ptr;
node->size = size;
node->file = file;
node->line = line;
node->next = g_tracker_head;
g_tracker_head = node;
g_active_allocations++;
g_total_allocated_bytes += size;
}
/* 内部辅助:从追踪器中移除释放的记录 */
C_STATIC_FORCE_INLINE
void c_tracker_remove(void* ptr) {
if (!ptr) return;
c_MemoryNode_t* curr = g_tracker_head;
c_MemoryNode_t* prev = NULL;
while (curr) {
if (curr->address == ptr) {
if (prev) { prev->next = curr->next; }
else { g_tracker_head = curr->next; }
g_total_allocated_bytes -= curr->size;
g_active_allocations--;
free(curr);
return;
}
prev = curr;
curr = curr->next;
}
}
/* 内部辅助:根据旧指针反查其原始分配大小(用于 POSIX 链下手动迁移数据) */
C_STATIC_FORCE_INLINE
c_size_t c_tracker_get_size(void* ptr) {
c_MemoryNode_t* curr = g_tracker_head;
while (curr) {
if (curr->address == ptr) return curr->size;
curr = curr->next;
}
return 0;
}
C_STATIC_FORCE_INLINE
void c_tracker_update(void* old_ptr, void* new_ptr, size_t new_size, const char* file, int line) {
if (!old_ptr) {
c_tracker_add(new_ptr, new_size, file, line);
return;
}
c_MemoryNode_t* curr = g_tracker_head;
while (curr) {
if (curr->address == old_ptr) {
// 先扣除旧的全局字节计数,加上新的
g_total_allocated_bytes -= curr->size;
g_total_allocated_bytes += new_size;
// 更新节点内部物理信息
curr->address = new_ptr;
curr->size = new_size;
curr->file = file;
curr->line = line;
return;
}
curr = curr->next;
}
/* 防御边界:如果追踪器里没找到旧指针(例如用户混用了外部指针),则强制当作新指针加入 */
c_tracker_add(new_ptr, new_size, file, line);
}
#endif
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void* c_Memory_Aligned_Alloc(c_size_t alignment, c_size_t size, const char* file, int line) {
if (size == 0) return NULL;
void* raw_ptr = NULL;
/* 确保对齐边界合法(必须是2的幂且大于指针大小) */
if (alignment < sizeof(void*)) alignment = sizeof(void*);
#if C_IS_OS_WINDOWS
/* 无论是 MSVC 还是您的 MSYS2 MinGW,在 Windows 上均调用此原生安全接口 */
raw_ptr = _aligned_malloc(size, alignment);
#elif C_IS_OS_MACOS
/* macOS 原生 malloc 在满足边界时已经高度对齐,或者使用 posix_memalign */
if (posix_memalign(&raw_ptr, alignment, size) != 0) { raw_ptr = NULL; }
#elif C_IS_OS_LINUX || C_IS_OS_FREEBSD
/* Linux 和 FreeBSD 的标准 POSIX 对齐接口 */
if (posix_memalign(&raw_ptr, alignment, size) != 0) { raw_ptr = NULL; }
#else
/* 终极兜底降级方案:常规分配(不对齐) */
raw_ptr = malloc(size);
#endif
#if !defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)
/* 注入追踪器 */
if (C_LIKELY(raw_ptr)) {
c_tracker_add(raw_ptr, size, file, line);
}
#endif
return raw_ptr;
}
void c_Memory_Aligned_Free(void* ptr, const char* file, int line) {
if (!ptr) return;
C_UNUSED(file);
C_UNUSED(line);
#if !defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)
/* 从日志中移除 */
c_tracker_remove(ptr);
#endif
#if C_IS_OS_WINDOWS
_aligned_free(ptr); /* Windows 的对齐内存必须用配套的 free 释放 */
#else
free(ptr); /* POSIX (Linux/Mac/FreeBSD) 的 posix_memalign 直接用常规 free 即可 */
#endif
}
void* c_Memory_Aligned_Calloc(c_size_t alignment, c_size_t num, c_size_t size, const char* file, int line) {
c_size_t total_bytes = num * size;
if (total_bytes == 0) return NULL;
// 直接复用我们写好的跨平台对齐分配器
void* ptr = c_Memory_Aligned_Alloc(alignment, total_bytes, file, line);
if (C_LIKELY(ptr)) {
// 强制物理内存清零,保证安全性
memset(ptr, 0, total_bytes);
}
return ptr;
}
void* c_Memory_Aligned_Realloc(size_t alignment, void* ptr, size_t new_size, const char* file, int line) {
#if !(!defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)) && defined(C_MEMORY_CHECK_ENABLE)
/* Debug 模式下的野指针前置拦截 */
if (ptr != NULL) {
if (C_UNLIKELY(!c_tracker_exists(ptr))) {
fprintf(stderr, "🚨 [CRITICAL ERROR] %s:%d 试图用未知野指针调用 Aligned_Realloc: %p\n", file, line, ptr);
assert(0 && "c_Memory_Aligned_Realloc Fail: Wild pointer!");
}
}
#endif
if (!ptr) return c_Memory_Aligned_Alloc(alignment, new_size, file, line);
if (new_size == 0) {
c_Memory_Aligned_Free(ptr, file, line);
return NULL;
}
if (alignment < sizeof(void*)) alignment = sizeof(void*);
void* new_ptr = NULL;
#if !(!defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)) && !C_IS_OS_WINDOWS
/* Debug 模式下非 Windows 系统的“严格毒化迁移” */
c_size_t old_size = c_tracker_get_size(ptr);
new_ptr = c_Memory_Aligned_Alloc(alignment, new_size, file, line);
if (C_LIKELY(new_ptr)) {
c_size_t copy_size = (old_size < new_size) ? old_size : new_size;
if (copy_size > 0) memcpy(new_ptr, ptr, copy_size);
memset(ptr, 0xDD, old_size); /* 毒化 */
c_Memory_Aligned_Free(ptr, file, line);
c_tracker_update(NULL, new_ptr, new_size, file, line);
}
#else
/* Release 生产环境或 Windows 环境下的原生高性能逻辑 */
#if C_IS_OS_WINDOWS
new_ptr = _aligned_realloc(ptr, new_size, alignment);
#else
new_ptr = c_Memory_Aligned_Alloc(alignment, new_size, file, line);
if (C_LIKELY(new_ptr)) {
memcpy(new_ptr, ptr, new_size);
c_Memory_Aligned_Free(ptr, file, line);
}
#endif
#if !defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)
if (C_LIKELY(new_ptr)) {
c_tracker_update(ptr, new_ptr, new_size, file, line);
}
#endif
#endif
#if !defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)
if (C_UNLIKELY(!new_ptr)) {
fprintf(stderr, "🚨 [OOM CRITICAL] %s:%d 内存耗尽,无法重分配 %lu 字节!\n", file, line, (unsigned long)new_size);
assert(0 && "Out of Memory!");
}
#endif
return new_ptr;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
void* c_Memory_Alloc(c_size_t nBytes, const char* file, int line) {
return c_Memory_Aligned_Alloc(C_ALIGN_SIZE, nBytes, file, line);
}
void* c_Memory_Calloc(c_size_t nCount, c_size_t nBytes, const char* file, int line) {
return c_Memory_Aligned_Calloc(C_ALIGN_SIZE, nCount, nBytes, file, line);
}
void* c_Memory_Realloc(void* ptr, c_size_t nBytes, const char* file, int line) {
return c_Memory_Aligned_Realloc(C_ALIGN_SIZE, ptr, nBytes, file, line);
}
void c_Memory_Free(void* ptr, const char* file, int line) {
c_Memory_Aligned_Free(ptr, file, line);
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#if !defined(NDEBUG) && defined(C_MEMORY_CHECK_ENABLE)
c_size_t c_memory_leak_report(void) {
if (g_active_allocations == 0) {
return 0;
}
printf("\n🚨 [MEMORY AUDIT] 检测到内存泄漏! 未释放的泄漏列表如下:\n");
c_MemoryNode_t* curr = g_tracker_head;
while (curr) {
printf(" -> 泄漏地址: %p | 大小: %lu 字节 | 位置: %s (第 %d 行)\n",
curr->address, (unsigned long)curr->size, curr->file, curr->line);
curr = curr->next;
}
return g_total_allocated_bytes;
}
void c_memory_tracker_reset(void) {
c_MemoryNode_t* curr = g_tracker_head;
while (curr) {
c_MemoryNode_t* next = curr->next;
free(curr);
curr = next;
}
g_tracker_head = NULL;
g_active_allocations = 0;
g_total_allocated_bytes = 0;
}
#endif
#endif