Pointers I — The Concept of Indirection
C-র হৃদয় — ঠিকানা দিয়ে কাজ করা
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.
2. Two Operators — & and *
#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
int *p = &x;-এর memory picture।
4. NULL — The "Points to Nothing" Value
#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;
}
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।
#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
- 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দেখুন। - 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; } - 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; } - 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; } - 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 নির্বিশেষে)।
- 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; } - 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; } - Use pointers to swap two elements at indices
iandjof 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; } - Given
int a = 5, what is&&a? Is it legal?&&aবৈধ কি না ব্যাখ্যা করুন।✨ Show Answer
না — বৈধ নয়।
&aএকটি rvalue (temporary pointer value), আর&operator lvalue চায়। তাই&&acompile error দেবে। GCC-তে অবশ্য&&labelএকটি non-standard extension — এটি label-এর address দেয়, কিন্তু সেটি ভিন্ন ব্যাপার। - Why does
int *p; *p = 5;often crash but sometimes "works"?int *p; *p = 5;কেন কখনো crash করে, কখনো করে না?✨ Show Answer
puninitialized, তাই এর মান random। সেই random address যদি আপনার process-এর valid memory-তে পড়ে, write চুপচাপ সফল হয় (কিন্তু অন্য variable-কে corrupt করে)। যদি সেটা মেমরির unmapped জায়গায় পড়ে, OS segfault দেয়। উভয়ই undefined behavior — কোনো অবস্থায়ই নির্ভরযোগ্য নয়। - 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; } - Declare a pointer of each primitive type and print its size.প্রতিটি primitive type-এর pointer ঘোষণা করে size প্রিন্ট করুন।
✨ Show Answer
Section 8 পয়েন্ট 5-এর
sizes.c-ই এই অনুশীলনের উত্তর। - 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; } - 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 ব্যবহার হয়। - 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-এ। - Read
<stddef.h>. What isptrdiff_t?<stddef.h>-এরptrdiff_tকী?✨ Show Answer
একই array-এর দুটি pointer বিয়োগ করলে যে integer type পাওয়া যায় সেটাই
ptrdiff_t। এটি signed — কারণp1 - p2ঋণাত্মক হতে পারে। Size platform-নির্ভর, সাধারণত 64-bit সিস্টেমেlong-এর সমান। - 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; - Explain the difference between
const int *pandint *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 করা যাবে। - 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লাগবেই। - 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 (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
| Pointer | A variable that holds a memory address. | মেমরি ঠিকানা ধারণকারী variable। |
| Address | The 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। |
| Indirection | Accessing a value through a pointer. | Pointer-এর মাধ্যমে মান access করা। |
| NULL | A pointer constant meaning "points to nothing". | "কোনো কিছুতে নয়" — এমন pointer constant। |
| NULL Pointer Dereference | Bug — accessing memory through NULL — crashes program. | NULL pointer dereference করলে crash হয়। |
| Pointer Type | The type a pointer points to (e.g., int *). | Pointer যে type-এর দিকে নির্দেশ করে। |
| Wild Pointer | An uninitialized pointer. | Initialize না-করা pointer। |
| Dangling Pointer | A pointer to memory that has been freed. | Free হওয়া মেমরির pointer। |
| Pass by Reference | Passing 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.