C Programming Review
Description
Comprehensive review of C programming concepts essential for kernel development. These are userspace programs that demonstrate concepts you’ll use in kernel code.
Programs
1. pointers_demo.c
Master pointers - the most critical skill for kernel programming.
Topics Covered:
- Basic pointer operations
- Pointer arithmetic
- Pointers with structures
- Dynamic memory allocation
- Function pointers
- Pointer to pointer
- NULL pointer safety
- Common mistakes to avoid
- Linked list implementation
2. structs_demo.c
Understanding structures - heavily used in kernel.
Topics Covered:
- Basic structures
- Nested structures
- Structure with function pointers
- Bit fields for hardware registers
- Memory layout and padding
- Anonymous unions/structs
- Dynamic structures
- Flexible array members
- container_of pattern (kernel idiom)
Build & Run
# Build all
make
# Run tests
make test
# Or run individually
./pointers_demo
./structs_demo
# Clean
make clean
Expected Output
pointers_demo
╔════════════════════════════════════════════════╗
║ Pointer Fundamentals for Kernel Development ║
╚════════════════════════════════════════════════╝
=== Basic Pointers ===
x = 42
Address of x = 0x7ffc...
ptr points to 0x7ffc...
*ptr = 42
After *ptr = 100, x = 100
=== Pointer Arithmetic ===
...
structs_demo
╔════════════════════════════════════════════════╗
║ Structure Fundamentals for Kernel Development║
╚════════════════════════════════════════════════╝
=== Basic Structures ===
Device: id=1, name=device0, flags=0xff
...
Learning Objectives
After running these programs, you should understand:
✅ Pointers:
- What pointers are and how they work
- Pointer arithmetic
- The relationship between pointers and arrays
- How to safely use pointers
- Common pointer bugs and how to avoid them
✅ Structures:
- How to define and use structures
- Memory layout and padding
- Nested structures
- Function pointers in structures
- Bit fields for hardware access
- container_of pattern
Why These Matter for Kernel Development
Pointers in Kernel
// Kernel uses pointers EVERYWHERE
struct device *dev; // Device pointer
void __iomem *regs; // Hardware register pointer
char __user *buffer; // Userspace pointer
dma_addr_t dma_handle; // DMA address
// container_of to get parent structure
struct my_device *mydev = container_of(dev, struct my_device, dev);
Structures in Kernel
// Kernel structures with function pointers (ops)
struct file_operations {
int (*open)(struct inode *, struct file *);
ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
// ...
};
// Bit fields for hardware registers
struct control_reg {
unsigned int enable:1;
unsigned int mode:2;
unsigned int reserved:29;
};
Key Differences: Userspace vs Kernel
| Concept | Userspace | Kernel |
|---|---|---|
| Allocation | malloc() |
kmalloc() |
| Free | free() |
kfree() |
| Strings | printf() |
printk() |
| NULL check | Recommended | MANDATORY |
| Crash result | Program dies | System crashes |
Common Mistakes (Don’t Do This!)
// ❌ BAD: Returning pointer to local variable
int *bad_function(void) {
int x = 42;
return &x; // BUG! x is destroyed after return
}
// ✅ GOOD: Allocate on heap
int *good_function(void) {
int *p = malloc(sizeof(int));
if (!p) return NULL;
*p = 42;
return p; // Caller must free
}
// ❌ BAD: Use after free
int *p = malloc(sizeof(int));
free(p);
*p = 42; // BUG! Memory already freed
// ❌ BAD: Not checking NULL
int *p = malloc(sizeof(int));
*p = 42; // BUG! Might crash if allocation failed
// ✅ GOOD: Always check
int *p = malloc(sizeof(int));
if (!p) {
return -ENOMEM;
}
*p = 42;
Self-Test Questions
After running these programs, answer these:
- What does
p++do ifpis anint *?- Adds sizeof(int) bytes to the pointer
- What’s the difference between
.and->?.for structure,->for structure pointer
- Why use
container_of?- To get parent structure from embedded member
- What’s a memory leak?
- Allocated memory that’s never freed
- Why are bit fields useful?
- Directly map to hardware register bits
Next Steps
After mastering these concepts:
- ✅ Move to kernel modules:
cd ../01-hello/ - 📚 Read Chapter 0:
../../00-prerequisites.md - 💻 Try modifying the examples
- 🧪 Write your own pointer/structure exercises
Additional Practice
Try these exercises:
- Modify pointers_demo.c:
- Add a doubly-linked list
- Implement a binary tree
- Add error injection (simulate malloc failures)
- Modify structs_demo.c:
- Create your own register structure
- Implement a device with operations
- Practice container_of with different structures
Resources
- “The C Programming Language” by K&R
- “Expert C Programming” by Peter van der Linden
- “Understanding and Using C Pointers” by Richard Reese
Remember: Mastering pointers and structures is ESSENTIAL for kernel development. Take your time with these examples!