Elective Programming In C

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

9000102
Array `grades[3] = {90}` (rest initialized to 0)
100201302403504scores[0]scores[1]scores[2]scores[3]scores[4]
Array `scores[] = {10, 20, 30, 40, 50}` (size inferred to 5, rest zero-initialized)

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)

1,2,304,5,61
2D array `matrix[2][3]` (row-major order, memory layout)

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.

800901702marksmarks + 1marks + 2
Dynamic array after input: `marks = (int*)malloc(3 * sizeof(int))` (3 students)

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.

1021324354arrarr + 1arr + 2arr + 4
Pointer arithmetic: `arr` decays to `&arr[0]`, `*(arr + i) = arr[i]`

Pointer Arithmetic

  • ptr + i moves i * sizeof(data_type) bytes.
  • Example: int *ptr = arr; ptr += 2; skips 2 integers (8 bytes if int is 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
100201302arrarr + 2
Function call: `processArray(arr, 3);` (array decays to pointer)

In the Real World

  1. 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)).
  2. 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).
  3. 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.
  4. 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.
  5. Bank Loans (Interest Calculation)

    • Banks use arrays to store monthly installments. For a loan of P at rate r for n months:
      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

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

  1. Buffer Overflow:

    int arr[5] = {1, 2, 3};
    arr[5] = 10;  // WRONG! Accesses memory outside array.
    

    Fix: Always check bounds (if (i < n)).

  2. Memory Leaks:

    int *ptr = malloc(10 * sizeof(int));
    // Forgot to free(ptr);
    

    Fix: Use free(ptr) after use.

  3. Pointer vs. Array Confusion:

    int arr[3] = {1, 2, 3};
    int *ptr = arr;
    printf("%d", ptr[1]);  // 2 (same as arr[1])
    

Exam Tip

  1. For Programs:

    • Always declare array size correctly (e.g., int n; scanf("%d", &n); int arr[n]; is invalid in standard C; use malloc).
    • Use pointer notation (*(arr + i)) in functions to show understanding.
    • Trace tables are your friend! Show step-by-step memory changes for dynamic allocation.
  2. For Theory:

    • Advantages of arrays: Contiguous memory, fast access, scalability.
    • DMA functions: Know malloc (uninitialized), calloc (zeroed), realloc (resize), free (release).
    • Pointer arithmetic: ptr + i moves i * sizeof(type) bytes.
  3. 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…