plugins/languages/c/skills/memory/SKILL.md
C memory management conventions: safe malloc/calloc/realloc patterns, free + NULL, alignment (aligned_alloc, posix_memalign, _Alignas), memory pools/arenas, RAII-like __attribute__((cleanup)), and leak/error detection with Valgrind, AddressSanitizer, MemorySanitizer, LeakSanitizer. Use when allocating memory, debugging leaks, designing cache-friendly layouts, or hardening against UAF / double-free. Triggers on "malloc 检查", "内存泄漏", "valgrind", "asan", "use-after-free", "double free", "内存对齐", "aligned_alloc", "内存池", "arena allocator".
npx skillsauth add lazygophers/ccplugin c-memoryInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
malloc / calloc / realloc 返回值必须检查。realloc 必须用临时指针接住,失败时原指针仍有效。sizeof 用 sizeof(*ptr) 而非 sizeof(Type),避免类型 / 指针不一致。free 后立即将指针置 NULL,杜绝 UAF / double-free。c-error 中 safe_multiply)。aligned_alloc(C11) 或 posix_memalign。malloc 直调。c-embedded)。// malloc
T *p = malloc(n * sizeof(*p));
if (!p) { perror("malloc"); goto cleanup; }
// calloc:零初始化,自动内置溢出检查
T *p = calloc(n, sizeof(*p));
if (!p) { perror("calloc"); goto cleanup; }
// realloc:临时指针模式
T *tmp = realloc(p, new_n * sizeof(*p));
if (!tmp) { perror("realloc"); goto cleanup; }
p = tmp;
// 释放
free(p);
p = NULL;
cleanup 属性)static inline void auto_free(void *pp) { free(*(void **)pp); }
#define AUTO_FREE __attribute__((cleanup(auto_free)))
void demo(void) {
AUTO_FREE char *buf = malloc(256);
if (!buf) return; // buf 作用域结束时自动 free
/* ... */
}
C23 可结合 [[gnu::cleanup(auto_free)]] 语法。
// C11 aligned_alloc:size 必须是 alignment 的整数倍
void *p = aligned_alloc(64, 1024);
// POSIX
void *q = NULL;
if (posix_memalign(&q, 64, 1024) != 0) { perror("posix_memalign"); }
// 缓存行对齐结构体
_Alignas(64) struct CacheLine { int data[16]; };
static_assert(_Alignof(struct CacheLine) == 64, "cache line align");
typedef struct { uint8_t *base; size_t cap, used; } Arena;
Arena *arena_new(size_t cap) {
Arena *a = malloc(sizeof *a);
if (!a) return NULL;
a->base = malloc(cap);
if (!a->base) { free(a); return NULL; }
a->cap = cap; a->used = 0;
return a;
}
void *arena_alloc(Arena *a, size_t n) {
n = (n + 7) & ~(size_t)7; // 8 字节对齐
if (a->used + n > a->cap) return NULL;
void *p = a->base + a->used; a->used += n; return p;
}
void arena_free(Arena *a) { if (a) { free(a->base); free(a); } }
| 工具 | 调用 | 用途 | 兼容性 |
|------|------|------|-------|
| Valgrind memcheck | valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=1 ./prog | 泄漏、越界、未初始化(10–50× 慢);检测不到栈/全局溢出 | 通用 |
| AddressSanitizer | -fsanitize=address -fno-omit-frame-pointer -g | 堆/栈/全局越界、UAF、double-free | GCC/Clang,与 UBSan 兼容 |
| LeakSanitizer | -fsanitize=leak 或 ASan 自带 | 仅泄漏,开销低 | GCC/Clang |
| MemorySanitizer | clang -fsanitize=memory -fno-omit-frame-pointer | 未初始化读取;需重编译所有依赖 | 仅 Clang,独立运行 |
| mtrack / heaptrack | heaptrack ./prog | 分配画像、火焰图 | Linux |
ASan + UBSan = 日常开发;提交前再跑 Valgrind;怀疑未初始化时用 MSan;与 TSan 不可同跑。
// calloc 内置溢出检查;手写 malloc 时显式校验
if (n > SIZE_MAX / sizeof(T)) return ERR_OVERFLOW;
T *p = malloc(n * sizeof(*p));
// reallocarray (glibc/BSD) 自动检查溢出
T *tmp = reallocarray(p, new_n, sizeof(*p));
if (!tmp) { /* p 仍有效 */ }
free(p); p = NULL; 配对sizeof(*p) 而非 sizeof(Type)aligned_alloc / posix_memalignmalloc/freedevelopment
Go 数据库规范——GORM Model 命名 ModelXxx、表名单数、枚举 uint8 + 常量、索引 idx_ 前缀 + deleted_at leading column、禁 time.Time 统一 int64 unix、禁指针/nullable 字段、TEXT/BLOB/JSON 禁 default、AutoMigrate 禁改主键。设计 DB model、写 GORM tag、建索引、做 migration 审查时触发。
development
Go HTTP API 规范——响应始终 200 + body code 字段、路由 /api/* 全 POST 单段 <Action><Model>、中间件逐路由注册禁 Group(prefix,mw...)、handler 仅返回 (rsp,error)、认证走 header。设计 HTTP API、写路由/handler/中间件时触发。
development
Go 项目结构规范——三层架构(API → Impl → State)、全局状态模式、internal/ 私有包、cmd/ 仅 main.go、go.work 多模块、禁止 Repository 接口和 DI 容器、struct 公共字段开头全 omitempty、handler var rsp 顶声明、禁 legacy migration。设计项目骨架、新建目录、组织包、做架构评审时触发。
development
Go 命名规范——Id/Uid 字段(非 ID)、IsActive/HasMFA 布尔前缀、CreatedAt 时间字段、接收者统一用 p、包名全小写无下划线、泛型类型参数描述性命名、集合字段 xxx_list 禁 xxxs 复数、Enum 0 值 XxxNil 禁 Unknown、禁 Status 统一 State、Set/Update 语义区分。定义结构体字段、函数、变量、包、接收者名、泛型、枚举时触发。