C
Avoid common C mistakes — memory leaks, buffer overflows, undefined behavior, and pointer traps.
Files2
View on GitHubSKILL.mdskills/ivangdavila/c/SKILL.md
GitHubMemory Management
- Every
mallocneeds afree— track ownership, free once only free(ptr); ptr = NULL;— prevents use-after-free- Check
mallocreturn — can return NULL on failure calloczeros memory —mallocleaves garbage- Memory leaks on early return — ensure cleanup path for all exits
Buffer Overflows
strcpydoesn't check bounds — usestrncpyorsnprintfgetsis never safe — removed in C11, usefgetssprintfcan overflow — usesnprintfwith buffer size- Array index not checked — manual bounds checking required
- Stack buffer overflow corrupts return address — security vulnerability
Strings
- Strings need null terminator
\0—strncpymay not add it if truncated strlendoesn't count null — allocatestrlen(s) + 1- String literals are immutable — modifying causes undefined behavior
sizeof(str)vsstrlen(str)— sizeof includes null, strlen doesn'tchar str[]copies,char *strpoints to literal — different behavior
Pointers
- Uninitialized pointer is garbage — always initialize or set to NULL
- Dereferencing NULL is undefined — check before use
- Pointer arithmetic in bytes vs elements —
p + 1advances by sizeof(*p) - Array decays to pointer —
sizeof(arr)in function gives pointer size - Returning pointer to local — stack frame gone, dangling pointer
Undefined Behavior
- Signed integer overflow is undefined — not wrap-around like unsigned
- Uninitialized variable read — garbage value, unpredictable
- Modifying variable twice between sequence points —
i++ + i++undefined - Null pointer dereference — crash or worse
- Shift by negative or >= width — undefined
Integer Gotchas
- Integer promotion in expressions — small types promote to int
- Unsigned vs signed comparison — signed converted to unsigned, negative becomes large
sizeofreturnssize_t(unsigned) — subtraction can wrap- Division truncates toward zero —
-7 / 2is-3, not-4
Arrays
- Array size must be constant (before C99 VLAs) — use malloc for dynamic
- VLAs can stack overflow — no size limit check, avoid for large/variable sizes
arr[i]is*(arr + i)— pointer arithmetic under the hood- Multidimensional arrays contiguous —
arr[i][j]isarr[i * cols + j]equivalent - Can't return array — return pointer to static or allocated memory
Preprocessor
- Macro arguments evaluated multiple times —
MAX(i++, j)increments i multiple times - Wrap macro body in
do { ... } while(0)— for statement-like macros - Wrap arguments in parentheses —
#define SQ(x) ((x) * (x)) #includeorder matters — headers may depend on prior includes
Common Mistakes
=vs==in conditions —if (x = 5)assigns, always true- Missing
breakin switch — falls through to next case sizeof(ptr)gives pointer size — not array or allocated size- Forgetting to flush stdout —
printfwithout\nmay not appear fopenreturns NULL on failure — always check before using file pointer