Pointers I — The Concept of Indirection

C-র হৃদয় — ঠিকানা দিয়ে কাজ করা

~45 min Advanced 20 practice problems Live code

1. Memory Is an Array of Bytes

Your computer's RAM is one giant array, indexed by addresses. A pointer is a variable that holds an address — an index into that array.

কম্পিউটারের RAM-কে কল্পনা করুন একটি বিশাল array হিসেবে, যার প্রতিটি byte-এর একটি ঠিকানা (address) আছে। একটি pointer হলো এমন একটি variable যা এই ঠিকানা ধারণ করে।

2. Two Operators — & and *

ptr_basics.c
#include <stdio.h>

int main(void) {
    int x = 42;
    int *p = &x;             // p holds the address of x

    printf("value of x : %d\n", x);
    printf("address &x : %p\n", (void*)&x);
    printf("p          : %p\n", (void*)p);
    printf("*p         : %d\n", *p);     // dereference → 42

    *p = 100;                  // modify x through p
    printf("x is now   : %d\n", x);
    return 0;
}
  • &x — address of x (কোথায় আছে)।
  • *p — value at the address p holds (সেই জায়গায় কী আছে)।
  • int *p; — p একটি pointer যা একটি int-এর দিকে দেখায়।

3. Memory Diagram

42 x address 0x7f4 0x7f4 p (int *) address 0x9a0 p points to x Figure 14.1 — int *p = &x;-এর memory picture।

4. NULL — The "Points to Nothing" Value

null_ptr.c
#include <stdio.h>

int main(void) {
    int *p = NULL;
    if (p)   printf("Not null\n");
    else    printf("Pointer is NULL\n");

    int x = 5;
    p = &x;
    if (p) printf("*p = %d\n", *p);
    return 0;
}
Dereferencing NULL = crash Program সাধারণ ভাবে segfault হয়। সবসময় dereference-এর আগে pointer-এর NULL check করুন, বিশেষ করে malloc, fopen ইত্যাদি থেকে পাওয়া pointer-এ।

5. Pointers to Different Types

char   *pc;
int    *pi;
double *pd;
void   *pv;   // generic pointer — cannot be dereferenced directly

Pointer-এর type ঠিক করে: dereference কীভাবে হবে (কত byte পড়বে) এবং pointer arithmetic-এ প্রতি ধাপে কত byte এগোবে।

6. Why Pointers Matter

  • Caller-এর ডেটা modify করতে পারা (pass by reference-এর মতো)।
  • বড় struct copy না করে efficiently পাঠানো।
  • Dynamic memory (malloc) — heap থেকে জায়গা নেওয়া।
  • Linked list, tree, graph — সব pointer-এর উপর তৈরি।
  • Function pointer — callbacks, plugin system।
mod_through_ptr.c
#include <stdio.h>

void double_it(int *p) { *p = *p * 2; }

int main(void) {
    int x = 21;
    double_it(&x);
    printf("x = %d\n", x);   // 42
    return 0;
}

7. Common Pointer Pitfalls

❌ Bugs

int *p;          // uninitialized!
*p = 5;          // writes to random address

int *q = NULL;
*q = 1;          // segfault

free(q); free(q);// double free

int *r = malloc(10);
free(r); *r = 5; // use after free

✅ Safe Idioms

int *p = NULL;
if (cond) p = &x;
if (p) *p = 5;

// after free, clear the pointer:
free(q); q = NULL;

8. Practice Problems

  1. Declare an int, a pointer to it, print both the value and the address.
    একটি int ও তার pointer ঘোষণা করে value ও address উভয়ই প্রিন্ট করুন।
    ✨ Show Answer

    Section 2-এর ptr_basics.c দেখুন।

  2. Write void inc(int *p) that increments the pointed int.
    Pointer-এর মাধ্যমে একটি int-কে increment করার function লিখুন।
    ✨ Show Answer
    inc.c
    #include <stdio.h>
    void inc(int *p) { (*p)++; }
    int main(void) {
        int x = 10;
        inc(&x); inc(&x); inc(&x);
        printf("x = %d\n", x);
        return 0;
    }
  3. Write void swap(int *, int *) — and verify.
    swap লিখে যাচাই করুন।
    ✨ Show Answer
    swap.c
    #include <stdio.h>
    void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; }
    int main(void) {
        int x = 7, y = 13;
        swap(&x, &y);
        printf("x=%d, y=%d\n", x, y);
        return 0;
    }
  4. Write void min_max(int *a, int n, int *mn, int *mx) using output parameters.
    Output parameter ব্যবহার করে min ও max একসাথে return করুন।
    ✨ Show Answer
    minmax.c
    #include <stdio.h>
    void min_max(const int *a, int n, int *mn, int *mx) {
        *mn = *mx = a[0];
        for (int i = 1; i < n; i++) {
            if (a[i] < *mn) *mn = a[i];
            if (a[i] > *mx) *mx = a[i];
        }
    }
    int main(void) {
        int a[] = {42, 7, 99, 3, 21};
        int mn, mx;
        min_max(a, 5, &mn, &mx);
        printf("min=%d max=%d\n", mn, mx);
        return 0;
    }
  5. Print the size of a pointer on your system. Compare with sizeof(int).
    Pointer-এর size প্রিন্ট করুন এবং sizeof(int)-এর সাথে তুলনা করুন।
    ✨ Show Answer
    sizes.c
    #include <stdio.h>
    int main(void) {
        printf("sizeof(int)      = %zu\n", sizeof(int));
        printf("sizeof(int *)    = %zu\n", sizeof(int*));
        printf("sizeof(char *)   = %zu\n", sizeof(char*));
        printf("sizeof(double *) = %zu\n", sizeof(double*));
        return 0;
    }

    ৬৪-বিট সিস্টেমে সব pointer-এর size 8 byte (target type নির্বিশেষে)।

  6. Return two values via pointers: quotient and remainder.
    Pointer দিয়ে quotient ও remainder একসাথে return করুন।
    ✨ Show Answer
    divmod.c
    #include <stdio.h>
    void divmod(int a, int b, int *q, int *r) {
        *q = a / b;
        *r = a % b;
    }
    int main(void) {
        int q, r;
        divmod(17, 5, &q, &r);
        printf("17 / 5 = %d remainder %d\n", q, r);
        return 0;
    }
  7. Show that free(NULL) is safe.
    দেখান যে free(NULL) নিরাপদ।
    ✨ Show Answer

    C standard অনুযায়ী free(NULL) কিছুই করে না — এটি বৈধ এবং নিরাপদ। অনেকেই ভুল করে ভাবেন এটি crash করবে।

    free_null.c
    #include <stdlib.h>
    #include <stdio.h>
    int main(void) {
        int *p = NULL;
        free(p);                      // perfectly legal
        puts("No crash. free(NULL) is a no-op.");
        return 0;
    }
  8. Use pointers to swap two elements at indices i and j of an array.
    Pointer ব্যবহার করে array-এর দুটি index-এর element swap করুন।
    ✨ Show Answer
    swap_idx.c
    #include <stdio.h>
    int main(void) {
        int a[] = {10, 20, 30, 40, 50};
        int i = 1, j = 3;
        int *pi = &a[i], *pj = &a[j];
        int t = *pi; *pi = *pj; *pj = t;
        for (int k = 0; k < 5; k++) printf("%d ", a[k]);
        putchar('\n');
        return 0;
    }
  9. Given int a = 5, what is &&a? Is it legal?
    &&a বৈধ কি না ব্যাখ্যা করুন।
    ✨ Show Answer

    না — বৈধ নয়। &a একটি rvalue (temporary pointer value), আর & operator lvalue চায়। তাই &&a compile error দেবে। GCC-তে অবশ্য &&label একটি non-standard extension — এটি label-এর address দেয়, কিন্তু সেটি ভিন্ন ব্যাপার।

  10. Why does int *p; *p = 5; often crash but sometimes "works"?
    int *p; *p = 5; কেন কখনো crash করে, কখনো করে না?
    ✨ Show Answer

    p uninitialized, তাই এর মান random। সেই random address যদি আপনার process-এর valid memory-তে পড়ে, write চুপচাপ সফল হয় (কিন্তু অন্য variable-কে corrupt করে)। যদি সেটা মেমরির unmapped জায়গায় পড়ে, OS segfault দেয়। উভয়ই undefined behavior — কোনো অবস্থায়ই নির্ভরযোগ্য নয়।

  11. Write a macro that safely frees a pointer and sets it to NULL.
    এমন একটি macro লিখুন যা pointer free করে ও NULL বসিয়ে দেয়।
    ✨ Show Answer
    safe_free.c
    #include <stdio.h>
    #include <stdlib.h>
    
    #define SAFE_FREE(p) do { free(p); (p) = NULL; } while (0)
    
    int main(void) {
        int *p = malloc(sizeof(int));
        *p = 42;
        printf("*p = %d\n", *p);
        SAFE_FREE(p);
        printf("after SAFE_FREE, p = %s\n", p == NULL ? "NULL" : "not null");
        return 0;
    }
  12. Declare a pointer of each primitive type and print its size.
    প্রতিটি primitive type-এর pointer ঘোষণা করে size প্রিন্ট করুন।
    ✨ Show Answer

    Section 8 পয়েন্ট 5-এর sizes.c-ই এই অনুশীলনের উত্তর।

  13. Build a pointer to pointer — int **pp — and dereference twice.
    Pointer to pointer বানিয়ে দুইবার dereference করুন।
    ✨ Show Answer
    pp.c
    #include <stdio.h>
    int main(void) {
        int x = 5;
        int *p = &x;
        int **pp = &p;
        printf("x   = %d\n", x);
        printf("*p  = %d\n", *p);
        printf("**pp= %d\n", **pp);
        return 0;
    }
  14. Write a function that takes a pointer to a struct and modifies one field.
    একটি struct-এর pointer নিয়ে তার একটি field modify করে এমন function লিখুন।
    ✨ Show Answer
    struct_mod.c
    #include <stdio.h>
    typedef struct { char name[32]; int gpa; } Student;
    
    void grant_bonus(Student *s) { s->gpa += 5; }
    
    int main(void) {
        Student s = { "Arif", 90 };
        grant_bonus(&s);
        printf("%s → %d\n", s.name, s.gpa);
        return 0;
    }

    Pointer দিয়ে struct-এর field access করতে -> operator ব্যবহার হয়।

  15. Trace memory: draw (on paper) the boxes-and-arrows diagram for a pointer-to-pointer.
    Pointer-to-pointer-এর জন্য boxes-and-arrows diagram আঁকুন।
    ✨ Show Answer

    তিনটি box: x (5) → p (address of x) → pp (address of p)। Box-গুলির মধ্যে তীর চিহ্ন দিন। Dereference একবার করলে আপনি p-তে পৌঁছান, দুইবার করলে x-এ।

  16. Read <stddef.h>. What is ptrdiff_t?
    <stddef.h>-এর ptrdiff_t কী?
    ✨ Show Answer

    একই array-এর দুটি pointer বিয়োগ করলে যে integer type পাওয়া যায় সেটাই ptrdiff_t। এটি signed — কারণ p1 - p2 ঋণাত্মক হতে পারে। Size platform-নির্ভর, সাধারণত 64-bit সিস্টেমে long-এর সমান।

  17. Show two different ways to initialize a pointer to NULL.
    Pointer-কে NULL-এ initialize করার দুটি উপায় দেখান।
    ✨ Show Answer
    int *p1 = NULL;    // from <stddef.h> / <stdio.h>
    int *p2 = 0;       // implicit conversion of 0 to a null pointer
    // C23 adds nullptr for type-safe null:
    // int *p3 = nullptr;
  18. Explain the difference between const int *p and int *const p.
    const int *p ও int *const p-এর পার্থক্য।
    ✨ Show Answer

    const int *p — "constant int-এর pointer"। p অন্য int-এ point করতে পারে, কিন্তু *p দিয়ে value modify করা যাবে না। int *const p — "constant pointer to int"। p যেখানে দেখাচ্ছে সেটা বদলানো যাবে না, কিন্তু *p দিয়ে value modify করা যাবে।

  19. Compare two strings using pointer comparison vs strcmp.
    Pointer comparison ও strcmp-এর মধ্যে পার্থক্য দেখান।
    ✨ Show Answer
    strcmp_vs_ptr.c
    #include <stdio.h>
    #include <string.h>
    int main(void) {
        char a[] = "hello";
        char b[] = "hello";
        printf("pointer == : %s\n", (a == b)             ? "same address" : "different addresses");
        printf("strcmp     : %s\n", strcmp(a, b) == 0 ? "same content" : "different content");
        return 0;
    }

    Pointer comparison শুধু memory ঠিকানা মেলায়; content মেলাতে strcmp লাগবেই।

  20. In one paragraph, explain to a friend why pointers matter.
    একটি অনুচ্ছেদে ব্যাখ্যা করুন — pointer কেন গুরুত্বপূর্ণ।
    ✨ Show Answer

    Pointer-এর কারণেই C এত শক্তিশালী। এটি আপনাকে function থেকে caller-এর variable modify করার সুযোগ দেয় (pass-by-reference-এর মতো), বড় struct বা array কপি না করে efficient-ভাবে পাঠাতে দেয়, এবং heap-এ dynamic memory allocate/free করতে দেয়। Linked list, tree, graph — যেকোনো জটিল data structure আসলে pointer-এর উপরেই দাঁড়িয়ে থাকে। Function pointer আবার callback, event-loop ও plugin system-এর ভিত্তি। সংক্ষেপে, pointer না বুঝলে C শেখা অসম্পূর্ণ থেকে যায়।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
PointerA variable that holds a memory address.মেমরি ঠিকানা ধারণকারী variable।
AddressThe numeric location of a byte in memory.মেমরিতে byte-এর সংখ্যাগত অবস্থান।
Address-of (&)Operator that returns a variable's address.Variable-এর ঠিকানা ফেরত দেওয়া operator।
Dereference (*)Operator that follows a pointer to its target.Pointer-কে অনুসরণ করে target-এ যাওয়ার operator।
IndirectionAccessing a value through a pointer.Pointer-এর মাধ্যমে মান access করা।
NULLA pointer constant meaning "points to nothing"."কোনো কিছুতে নয়" — এমন pointer constant।
NULL Pointer DereferenceBug — accessing memory through NULL — crashes program.NULL pointer dereference করলে crash হয়।
Pointer TypeThe type a pointer points to (e.g., int *).Pointer যে type-এর দিকে নির্দেশ করে।
Wild PointerAn uninitialized pointer.Initialize না-করা pointer।
Dangling PointerA pointer to memory that has been freed.Free হওয়া মেমরির pointer।
Pass by ReferencePassing a pointer so a function can modify caller's variable.Pointer পাঠিয়ে caller-এর variable পরিবর্তনযোগ্য করা।
void *Generic pointer to any type.যেকোনো type-এর জন্য generic pointer।

Summary — Module 14

A pointer holds an address. & takes an address; * follows one. Always initialize pointers, check for NULL, and null them after free. The type of a pointer tells the compiler how to interpret the memory it points at.

Next Module → Pointers II — arithmetic, arrays এবং function parameters।