Assignment Overview
In this assignment, you will build a Memory Management Toolkit consisting of multiple C programs that demonstrate mastery of pointers. This comprehensive project requires you to apply ALL concepts from Module 5: pointer basics, pointer arithmetic, arrays with pointers, dynamic memory allocation (malloc, calloc, realloc, free), and function pointers.
Pointer Basics (5.1)
Declaration, initialization, dereferencing, address-of operator
Pointer Arithmetic (5.2)
Incrementing, decrementing, pointer differences, comparisons
Arrays and Pointers (5.3)
Array-pointer relationship, pointer notation, 2D arrays
Function Pointers (5.4)
Callbacks, jump tables, qsort, dynamic dispatch
The Scenario
EmbeddedTech Systems
You have been hired as an Embedded C Developer at EmbeddedTech Systems, a company that builds firmware for IoT devices. The lead engineer has given you this task:
"We need a set of reusable C utilities that demonstrate proper pointer usage and memory management. These will be used as templates for our firmware projects. Create programs showing pointer basics, dynamic arrays, string manipulation using pointers, matrix operations, and a calculator using function pointers. All code must be memory-safe with no leaks!"
Your Task
Create a collection of C programs that implement a complete pointer toolkit. Each program must
compile without warnings using gcc -Wall -Wextra, run without memory leaks, and
demonstrate the specific pointer concepts listed in the requirements.
Requirements
Your toolkit must include ALL of the following programs. Each program is mandatory and will be tested individually.
Pointer Basics Demo (pointer_basics.c)
Create a program that demonstrates fundamental pointer operations:
- Declare pointers to int, float, char, and double
- Initialize pointers using address-of operator (&)
- Print memory addresses using %p format specifier
- Dereference pointers to read and modify values
- Demonstrate pointer-to-pointer (double pointer)
// Example function signatures
void demonstrate_basic_pointers(void);
void demonstrate_pointer_to_pointer(void);
void print_variable_info(const char *name, void *ptr, size_t size);
Swap Functions Using Pointers (swap.c)
Create a program with multiple swap implementations:
void swap_int(int *a, int *b)- Swap two integersvoid swap_float(float *a, float *b)- Swap two floatsvoid swap_strings(char **s1, char **s2)- Swap two string pointersvoid swap_generic(void *a, void *b, size_t size)- Generic swap using memcpy- Demonstrate all four functions in main() with before/after output
// Must use pointer parameters to modify caller's variables
void swap_int(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
Dynamic Array Operations (dynamic_array.c)
Create a program that manages a dynamic integer array:
- Ask user for initial array size at runtime
- Use
malloc()to allocate the array - Fill array with user input values
- Implement:
calculate_sum(),calculate_average(),find_min(),find_max() - Implement
resize_array()usingrealloc() - Implement
reverse_array()using pointer arithmetic - Use
free()to deallocate memory before exit
// Example function signatures
int* create_array(int size);
void fill_array(int *arr, int size);
int calculate_sum(int *arr, int size);
double calculate_average(int *arr, int size);
int* resize_array(int *arr, int old_size, int new_size);
void reverse_array(int *arr, int size);
void free_array(int *arr);
String Manipulation with Pointers (string_pointers.c)
Implement string functions using pointer arithmetic only (no array indexing []):
int my_strlen(const char *str)- Calculate string lengthchar* my_strcpy(char *dest, const char *src)- Copy stringchar* my_strcat(char *dest, const char *src)- Concatenate stringsint my_strcmp(const char *s1, const char *s2)- Compare stringschar* my_strrev(char *str)- Reverse string in placeint count_char(const char *str, char c)- Count occurrences of character
// Must use pointer arithmetic, NOT array indexing
int my_strlen(const char *str) {
const char *p = str;
while (*p != '\0') {
p++;
}
return p - str;
}
2D Dynamic Matrix (matrix_dynamic.c)
Create a program that works with dynamically allocated 2D matrices:
int** create_matrix(int rows, int cols)- Allocate 2D arrayvoid fill_matrix(int **mat, int rows, int cols)- Fill with user inputvoid print_matrix(int **mat, int rows, int cols)- Display matrixint** transpose_matrix(int **mat, int rows, int cols)- Create transposed copyint** multiply_matrices(int **a, int **b, int r1, int c1, int c2)- Matrix multiplicationvoid free_matrix(int **mat, int rows)- Free all allocated memory
// Must allocate row pointers, then each row
int** create_matrix(int rows, int cols) {
int **mat = (int **)malloc(rows * sizeof(int *));
if (mat == NULL) return NULL;
for (int i = 0; i < rows; i++) {
mat[i] = (int *)malloc(cols * sizeof(int));
if (mat[i] == NULL) {
// Free previously allocated rows
for (int j = 0; j < i; j++) free(mat[j]);
free(mat);
return NULL;
}
}
return mat;
}
Calculator with Function Pointers (calculator.c)
Create a calculator using function pointers and jump tables:
- Define typedef for operation function:
typedef double (*Operation)(double, double) - Implement:
add(),subtract(),multiply(),divide(),power(),modulo() - Create a jump table (array of function pointers)
- Implement menu-driven interface that uses the jump table
- Handle division by zero gracefully
- Allow user to perform multiple calculations until exit
typedef double (*Operation)(double, double);
double add(double a, double b) { return a + b; }
double subtract(double a, double b) { return a - b; }
// ... more operations
int main() {
Operation operations[] = {add, subtract, multiply, divide, power};
const char *names[] = {"+", "-", "*", "/", "^"};
// Menu-driven calculator using operations array
}
Sorting with Comparators (sorting.c)
Create a program demonstrating qsort with custom comparators:
- Define a
Studentstructure with name, age, and gpa fields - Create array of students (at least 5)
- Implement comparator functions:
compare_by_name(),compare_by_age(),compare_by_gpa() - Use
qsort()to sort by each field - Display sorted results for each comparison
typedef struct {
char name[50];
int age;
float gpa;
} Student;
int compare_by_name(const void *a, const void *b);
int compare_by_age(const void *a, const void *b);
int compare_by_gpa_desc(const void *a, const void *b);
Submission
Create a public GitHub repository with the exact name shown below:
Required Repository Name
pointer-mastery-toolkit
Required Files
pointer-mastery-toolkit/
├── pointer_basics.c # Program 1: Pointer fundamentals
├── swap.c # Program 2: Swap functions
├── dynamic_array.c # Program 3: Dynamic array operations
├── string_pointers.c # Program 4: String manipulation
├── matrix_dynamic.c # Program 5: 2D dynamic matrices
├── calculator.c # Program 6: Function pointer calculator
├── sorting.c # Program 7: qsort with comparators
├── Makefile # Build all programs with: make all
└── README.md # Documentation (see requirements below)
README.md Must Include:
- Your full name and submission date
- Brief description of each program
- Compilation and usage instructions
- Any challenges faced and how you solved them
- Screenshot or output sample from at least 2 programs
Makefile Required:
CC = gcc
CFLAGS = -Wall -Wextra -std=c11
all: pointer_basics swap dynamic_array string_pointers matrix_dynamic calculator sorting
pointer_basics: pointer_basics.c
$(CC) $(CFLAGS) -o pointer_basics pointer_basics.c
# ... similar rules for other programs
clean:
rm -f pointer_basics swap dynamic_array string_pointers matrix_dynamic calculator sorting
Do Include
- All 7 programs implemented and working
- Comments explaining pointer operations
- Proper memory allocation and deallocation
- NULL pointer checks before dereferencing
- Error handling for malloc failures
- Makefile for easy compilation
- README.md with all required sections
Do Not Include
- Compiled binaries or object files
- Code with memory leaks (test with Valgrind)
- Array indexing [] in string_pointers.c (use pointer arithmetic)
- Hardcoded array sizes in dynamic programs
- Code that does not compile with -Wall -Wextra
- Missing free() calls for allocated memory
gcc -Wall -Wextra and ensure zero warnings.
Test with Valgrind: valgrind --leak-check=full ./program_name
Enter your GitHub username - we will verify your repository automatically
Grading Rubric
Your assignment will be graded on the following criteria:
| Criteria | Points | Description |
|---|---|---|
| Pointer Basics Demo | 15 | Correct pointer declaration, initialization, dereferencing, and double pointers |
| Swap Functions | 15 | All four swap functions work correctly with proper pointer usage |
| Dynamic Array | 25 | Proper malloc/realloc/free usage, all operations work, no memory leaks |
| String Manipulation | 25 | All functions use pointer arithmetic (no []), correct implementation |
| 2D Matrix Operations | 25 | Correct 2D allocation, transpose, multiply, and proper memory cleanup |
| Calculator with Function Pointers | 20 | Proper typedef, jump table implementation, menu-driven interface |
| Sorting with Comparators | 15 | Correct qsort usage, all three comparators work correctly |
| Code Quality and Documentation | 10 | Clean code, comments, Makefile, README, no compiler warnings |
| Total | 150 |
Ready to Submit?
Make sure you have completed all requirements and reviewed the grading rubric above.
Submit Your AssignmentWhat You Will Practice
Pointer Fundamentals (5.1)
Declaration, initialization, address-of operator, dereferencing, pointer-to-pointer
Pointer Arithmetic (5.2)
Incrementing, decrementing, pointer differences, traversing arrays with pointers
Dynamic Memory Management
malloc, calloc, realloc, free, detecting and preventing memory leaks
Function Pointers (5.4)
Callback functions, jump tables, typedef for function pointers, qsort comparators
Pro Tips
Memory Management
- Always check if malloc/calloc returns NULL
- Free memory in reverse order of allocation
- Set pointers to NULL after freeing
- Use Valgrind to detect leaks:
valgrind --leak-check=full
Debugging Pointers
- Print addresses with %p to trace pointer values
- Use GDB to step through pointer operations
- Enable all warnings:
-Wall -Wextra -Wpedantic - Initialize all pointers to NULL or valid address
Pointer Arithmetic
- Remember: ptr++ moves by sizeof(*ptr) bytes
- Array name decays to pointer to first element
- *(arr + i) is equivalent to arr[i]
- Pointer difference gives element count, not bytes
Common Mistakes
- Dereferencing NULL or uninitialized pointers
- Forgetting to free dynamically allocated memory
- Using pointer after free (dangling pointer)
- Off-by-one errors in pointer arithmetic