C Development
Write safe, efficient C code for systems programming.
When to use Writing C code Memory management issues System programming Embedded systems Performance-critical code Memory management Allocation patterns // Always check malloc void* ptr = malloc(size); if (ptr == NULL) { fprintf(stderr, "malloc failed\n"); return -1; }
// Pair malloc with free char* buffer = malloc(1024); // ... use buffer ... free(buffer); buffer = NULL; // Prevent use-after-free
// Use calloc for zero-initialized memory int* array = calloc(count, sizeof(int));
// Realloc safely void* new_ptr = realloc(ptr, new_size); if (new_ptr == NULL) { free(ptr); // Original still valid on failure return -1; } ptr = new_ptr;
Common patterns // RAII-style cleanup with goto int process_file(const char path) { int result = -1; FILE fp = NULL; char* buffer = NULL;
fp = fopen(path, "r");
if (!fp) goto cleanup;
buffer = malloc(1024);
if (!buffer) goto cleanup;
// ... process ...
result = 0;
cleanup: free(buffer); if (fp) fclose(fp); return result; }
Data structures // Linked list node typedef struct Node { void data; struct Node next; } Node;
// Dynamic array typedef struct { void** items; size_t count; size_t capacity; } DynArray;
int dynarray_push(DynArray arr, void item) { if (arr->count >= arr->capacity) { size_t new_cap = arr->capacity ? arr->capacity * 2 : 8; void* new_items = realloc(arr->items, new_cap * sizeof(void)); if (!new_items) return -1; arr->items = new_items; arr->capacity = new_cap; } arr->items[arr->count++] = item; return 0; }
Error handling // Check all system calls int fd = open(path, O_RDONLY); if (fd == -1) { perror("open"); return -1; }
ssize_t n = read(fd, buf, sizeof(buf)); if (n == -1) { perror("read"); close(fd); return -1; }
Debugging
Compile with debug symbols
gcc -g -Wall -Wextra -Werror -o prog prog.c
Run with valgrind
valgrind --leak-check=full ./prog
GDB debugging
gdb ./prog (gdb) break main (gdb) run (gdb) print variable (gdb) backtrace
Best practices Check all return values Initialize all variables Use const where possible Prefer stack over heap when size is known Use -Wall -Wextra -Werror flags Examples
Input: "Fix memory leak" Action: Run valgrind, trace allocation, ensure every malloc has free
Input: "Optimize this C code" Action: Profile with perf, identify hotspots, optimize critical path