The Philosophy
“C assumes you know what you are doing.” It does not have Garbage Collection. It does not stop you from accessing invalid memory. It is a razor-sharp tool that gives you direct access to the hardware.
- If you want to build a Web App, use JavaScript.
- If you want to build the Browser that runs the Web App, use C/C++.
1. The Compilation Process (Under the Hood) ⚙️
When you run gcc main.c, four distinct steps happen.
- Preprocessing (
.i): Handles#includeand#define. It essentially copy-pastes header files into your source. - Compilation (
.s): Translates C code into Assembly instructions specific to your CPU architecture (x86_64). - Assembly (
.o): Translates Assembly into Machine Code (Binary). This is the “Object File”. - Linking (
a.out): Combines your object file with standard libraries (libc) to create the final executable.
# See the steps manually
gcc -E main.c -o main.i # Preprocess
gcc -S main.i -o main.s # Compile
gcc -c main.s -o main.o # Assemble
gcc main.o -o main # Link2. Memory Anatomy 🧠
Understanding where your variables live is critical.
| Segment | Content | Lifetime |
|---|---|---|
| Code (Text) | The compiled machine instructions. Read-only. | Program duration. |
| Data | Global/Static variables initialized (int x = 10;). | Program duration. |
| BSS | Global/Static variables uninitialized (int x;). | Program duration. |
| Heap | Dynamic memory (malloc). Grows Up. | Until free() is called. |
| Stack | Local variables (int x). Grows Down. | Until function returns. |
3. Pointers (The Barrier to Entry) 👉
A Pointer is just a variable that holds a Memory Address instead of a value.
C
void pointerMagic() {
int x = 10;
int *ptr = &x; // 'ptr' stores the address of 'x'
printf("Address: %p\n", ptr); // 0x7ffee...
printf("Value: %d\n", *ptr); // 10 (Dereferencing)
*ptr = 20; // Change the value at that address
printf("x is now: %d\n", x); // x is 20
}
Pointer Arithmetic
Arrays in C are just pointers to the first element.
C
int arr[3] = {10, 20, 30};
int *p = arr;
printf("%d", *p); // 10
printf("%d", *(p + 1)); // 20 (Moves 4 bytes forward)
4. Manual Memory Management (The Danger Zone) 💣
You are the Garbage Collector. If you forget to free(), you leak RAM.
C
#include <stdlib.h>
void heapAllocation() {
// Allocate space for 100 integers
int *arr = (int*) malloc(100 * sizeof(int));
if (arr == NULL) {
// Always check if malloc failed (Out of Memory)
return;
}
arr[0] = 5;
// CRITICAL: Release memory when done
free(arr);
// OPTIONAL: Prevent dangling pointer
arr = NULL;
}
The “Double Free” Bug
Freeing the same pointer twice crashes the program and can lead to security exploits.
5. Structs & Unions 🏗️
Structs (Grouping Data)
The precursor to Classes.
C
struct Point {
int x;
int y;
};
struct Point p1 = {10, 20};
Unions (Memory Efficiency)
All members share the same memory location. Useful for embedded systems or low-level type punning.
C
union Data {
int i;
float f;
};
// Only 'i' OR 'f' can be used at one time.
// Writing to 'f' overwrites 'i'.
6. System Calls (Talking to the Kernel) 🐧
Standard C (printf) wraps System Calls (write). A Systems Engineer uses the Syscalls directly for performance.
C
#include <unistd.h>
#include <fcntl.h>
void lowLevelIO() {
// 1. Open File (Syscall)
int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
if (fd == -1) return; // Error
// 2. Write (Directly to File Descriptor)
char *msg = "Hello Kernel\n";
write(fd, msg, 13);
// 3. Close
close(fd);
}
Note: File Descriptors (0, 1, 2) correspond to Stdin, Stdout, Stderr.
7. Debugging with GDB & Valgrind 🕵️♂️
GDB (The GNU Debugger):
Step through code line-by-line.
Bash
gcc -g main.c -o main # Compile with debug symbols
gdb ./main
# Commands: run, break main, next, print variable
Valgrind (The Memory Leak Detector):
This tool runs your program and watches every single memory allocation.
Bash
valgrind --leak-check=full ./main
Output: definitely lost: 40 bytes in 1 blocks. (Means you forgot a free).
Linked Notes
-
Linux-Kernel-Internals - Where C runs.
-
CPP-Ultimate-Guide - The evolution of C.
-
Python-Advanced - How CPython is built on top of C.