Programming In CUnit 612 min read
Arrays, Dynamic Memory Allocation & Pointer Arithmetic in C
Unit 6 of Programming In C covers one-dimensional/multi-dimensional arrays (declaration, initialization, traversal, operations), dynamic memory allocation (malloc, calloc, realloc, free), pointer arithmetic, and real-world applications like sorting student records or managing transaction queues.
Arrays in C: The Foundation of Data Storage
Arrays are contiguous memory locations used to store multiple values of the same data type under a single variable name. They eliminate the need for multiple variables and simplify data manipulation.
1. One-Dimensional Arrays
Declaration & Initialization
int marks[5]; // Uninitialized array (garbage values)
int scores[] = {10, 20, 30, 40, 50}; // Size inferred (5)
int grades[3] = {90}; // Rest initialized to 0 (90, 0, 0)
Visualization: Array Memory Layout
```figure
{"type":"array","values":[0,0,0,0,0],"highlight":[0,4],"caption":"Default initialization: `int arr[5];` (all elements zero if uninitialized in some compilers)"}
| Index | 0 | 1 | 2 |
|-------|-----|-----|-----|
| Value | 10 | 20 | 30 |
#### **Traversal & Operations**
```c
#include <stdio.h>
int main() {
int arr[5] = {5, 10, 15, 20, 25};
// Sum of array elements
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += arr[i];
}
printf("Sum: %d\n", sum); // Output: 75
return 0;
}
Exam Tip: Always check array bounds (i < n) to avoid buffer overflow.
2. Multi-Dimensional Arrays (Matrices)
Declaration & Access
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
printf("%d", matrix[1][2]); // Output: 6
Visualization: 2D Array as a Matrix
Row 0: [1][2][3]
Row 1: [4][5][6]
Matrix Multiplication (Example)
#include <stdio.h>
int main() {
int A[2][3] = {{1, 2}, {3, 4}}; // 2x3
int B[3][2] = {{5, 6}, {7, 8}}; // 3x2
int C[2][2] = {0}; // Result (2x2)
```figure
{"type":"array","values":[[1,2,3],[4,5,6]],"caption":"Matrix A (2x3) for multiplication example"}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 3; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
// Print C
return 0;
}
Trace Table for C[0][0] Calculation:
| Step | i |
j |
k |
A[i][k] |
B[k][j] |
C[i][j] (Partial) |
|---|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 1 | 5 | 5 |
| 2 | 0 | 0 | 1 | 2 | 7 | 5 + 14 = 19 |
| 3 | 0 | 0 | 2 | - | - | 19 (final) |
Output:
C = [19, 22]
[43, 50]
Dynamic Memory Allocation (DMA)
Arrays declared with fixed size (int arr[10]) waste memory if unused or cause overflow if exceeded. Dynamic allocation solves this using malloc, calloc, realloc, and free.
Key Functions
| Function | Purpose | Example |
|---|---|---|
malloc |
Allocates uninitialized memory | ptr = malloc(5 * sizeof(int)); |
calloc |
Allocates zero-initialized memory | ptr = calloc(5, sizeof(int)); |
realloc |
Resizes allocated memory | ptr = realloc(ptr, 10 * sizeof(int)); |
free |
Releases memory | free(ptr); |
Visualization: Memory Allocation Steps
Example: Dynamic Array for Student Marks
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, *marks;
printf("Enter number of students: ");
scanf("%d", &n);
marks = (int*)calloc(n, sizeof(int)); // Zero-initialized
for (int i = 0; i < n; i++) {
printf("Enter mark %d: ", i+1);
scanf("%d", &marks[i]);
}
// Calculate average
float avg = 0;
for (int i = 0; i < n; i++) avg += marks[i];
printf("Average: %.2f\n", avg/n);
free(marks); // Prevent memory leak
return 0;
}
Trace for n = 3, Inputs: 80, 90, 70
| Step | Action | Memory State |
|---|---|---|
| 1 | marks = calloc(3, sizeof(int)) |
[0, 0, 0] (3 ints) |
| 2 | marks[0] = 80 |
[80, 0, 0] |
| 3 | marks[1] = 90 |
[80, 90, 0] |
| 4 | marks[2] = 70 |
[80, 90, 70] |
| 5 | avg = (80+90+70)/3 = 80 |
- |
| 6 | free(marks) |
Memory released |
Pointers & Arrays: The Hidden Connection
Arrays decay into pointers when passed to functions. Understanding pointer arithmetic is crucial for efficient array manipulation.
Pointer Arithmetic
ptr + imovesi * sizeof(data_type)bytes.- Example:
int *ptr = arr; ptr += 2;skips 2 integers (8 bytes ifintis 4 bytes).
Visualization: Pointer Arithmetic
```figure
{"type":"number-line","from":0,"to":20,"interval":{"from":0,"to":20,"step":4},"points":[{"x":0,"label":"arr (address of arr[0])"},{"x":4,"label":"arr + 1 (address of arr[1])"},{"x":8,"label":"arr + 2 (address of arr[2])"},{"x":16,"label":"arr + 4 (address of arr[4])"}],"caption":"Pointer arithmetic: `int arr[5] = {1, 2, 3, 4, 5};` (assuming `sizeof(int) = 4 bytes`)"}
| Pointer (`ptr`) | Value (`*ptr`) | Address (`ptr`) | Explanation |
|------------------|----------------|-----------------|---------------------------|
| `arr` | 10 | `&arr[0]` | Points to first element |
| `ptr + 1` | 20 | `&arr[1]` | Moves 4 bytes (1 int) |
| `ptr + 2` | 30 | `&arr[2]` | Moves 8 bytes (2 ints) |
### **Passing Arrays to Functions via Pointers**
```c
#include <stdio.h>
// Function to calculate sum using pointer
int sumArray(int *arr, int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += *(arr + i); // Equivalent to arr[i]
}
return sum;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printf("Sum: %d\n", sumArray(arr, 5)); // Output: 15
return 0;
}
Trace Table:
| Function Call | arr (Pointer) |
*(arr + i) |
sum |
|---|---|---|---|
sumArray(arr, 5) |
&arr[0] |
- | 0 |
i = 0 |
arr + 0 |
1 | 1 |
i = 1 |
arr + 1 |
2 | 3 |
i = 2 |
arr + 2 |
3 | 6 |
i = 3 |
arr + 3 |
4 | 10 |
i = 4 |
arr + 4 |
5 | 15 |
In the Real World
eSewa (Nepal): Transaction Queues
- Uses dynamic arrays to manage pending transactions. When a user pays a bill, the system appends the transaction to an array (or linked list) and processes it in FIFO order.
- Pointer arithmetic helps calculate memory offsets for quick access to transaction details (e.g.,
transaction_ptr + i * sizeof(Transaction)).
Khalti (Nepal): Fraud Detection
- Stores user transaction histories in multi-dimensional arrays (e.g.,
transactions[user_id][day][amount]). Algorithms scan these arrays to detect unusual patterns (e.g., sudden large transactions).
- Stores user transaction histories in multi-dimensional arrays (e.g.,
Daraz (Nepal): Order Processing
- Uses dynamic memory allocation to handle variable-order sizes. During sales events, the system allocates memory for thousands of orders and frees it after processing to avoid crashes.
NTC (Nepal Telecom): Network Routing Tables
- Routers use 2D arrays to store path costs between nodes (e.g.,
cost[source_node][destination_node]). Dijkstra’s algorithm (taught later) relies on array traversal to find the shortest path.
- Routers use 2D arrays to store path costs between nodes (e.g.,
Bank Loans (Interest Calculation)
- Banks use arrays to store monthly installments. For a loan of
Pat raterfornmonths:float installments[n]; for (int i = 0; i < n; i++) { installments[i] = P * (r/100) * pow(1 + r/100, n) / (pow(1 + r/100, n) - 1); } - Visualization: Loan Amortization Schedule
Month Installment Principal Interest Remaining Balance 1 8552.57 5257.43 3295.14 94742.57 2 8552.57 5305.14 3247.43 89437.43
- Banks use arrays to store monthly installments. For a loan of
Advantages of Arrays Over Variables
| Feature | Array | Single Variable |
|---|---|---|
| Memory Usage | Efficient (contiguous) | Inefficient (separate vars) |
| Access Speed | O(1) for random access | N/A |
| Scalability | Handles n elements easily |
Requires n variables |
| Use Case | Matrices, lists, tables | Single-value storage |
Disadvantage: Fixed size (unless dynamic allocation is used).
Common Pitfalls & Best Practices
Buffer Overflow:
int arr[5] = {1, 2, 3}; arr[5] = 10; // WRONG! Accesses memory outside array.Fix: Always check bounds (
if (i < n)).Memory Leaks:
int *ptr = malloc(10 * sizeof(int)); // Forgot to free(ptr);Fix: Use
free(ptr)after use.Pointer vs. Array Confusion:
int arr[3] = {1, 2, 3}; int *ptr = arr; printf("%d", ptr[1]); // 2 (same as arr[1])
Exam Tip
For Programs:
- Always declare array size correctly (e.g.,
int n; scanf("%d", &n); int arr[n];is invalid in standard C; usemalloc). - Use pointer notation (
*(arr + i)) in functions to show understanding. - Trace tables are your friend! Show step-by-step memory changes for dynamic allocation.
- Always declare array size correctly (e.g.,
For Theory:
- Advantages of arrays: Contiguous memory, fast access, scalability.
- DMA functions: Know
malloc(uninitialized),calloc(zeroed),realloc(resize),free(release). - Pointer arithmetic:
ptr + imovesi * sizeof(type)bytes.
Real-World Links:
- Relate array operations to sorting student marks, matrix multiplication for graphics, or transaction logs in eSewa.
- For dynamic allocation, mention memory-efficient systems like Daraz’s order processing.
Final Note: Arrays and dynamic memory are the backbone of efficient programming. Master these, and you’ll ace problems involving data storage, matrix operations, and memory management—key topics in exams and real-world coding!
In the real world
eSewa (Nepal) uses dynamic arrays to store pending transactions in a queue (FIFO). When a user pays a bill, the system appends the transaction to an array (or linked list) and processes it sequentially. Pointer arithmetic helps calculate memory offsets for quick access to transaction details (e.g.,
transaction_ptr + i * sizeof(Transaction)).Ncell’s call-center system uses multi-dimensional arrays to track customer call logs by date, time slots, and agent IDs (e.g.,
call_logs[30][24][10]for 30 days, 24 hours, 10 agents).Daraz’s inventory system employs pointers and dynamic memory to manage product stock levels. When a product sells out, the system reallocates memory for the next batch (e.g.,
realloc(product_stock, new_size * sizeof(int))) to avoid buffer overflow.
Based on the PU BE Computer (PU) syllabus for Programming In C, unit 6.
Discussion
Loading…