C పాయింటర్లు: బేసిక్స్, మెమరీ అడ్రస్లు & Dereferencing (*, &)

⚡ Modern C (C99 / C11 / C17 Standards) 🟢 Chapter 15 of 20 📂 Phase 04: అర్రేస్, స్ట్రింగ్స్ & పాయింటర్లు 📅 2026 Academic Edition
📌 Covered in this chapter: హోటల్ కీ-కార్డు ఎనాలజీ · RAM హెక్సాడెసిమల్ అడ్రస్లు · 64-bit 8-బైట్ల పాయింటర్ సైజు · & vs * ఆపరేటర్లు · పాయింటర్ అరిథ్‌మెటిక్ (ptr + 1) స్కేల్ ఫ్యాక్టర్ · void* జెనెరిక్ పాయింటర్లు · NULL, Wild, Dangling పాయింటర్లు · const పాయింటర్లు · RAM మెమరీ ఇన్‌స్పెక్టర్ ప్రాజెక్ట్ · ఇంటరాక్టివ్ క్విజ్

ఒక పెద్ద 5-స్టార్ లగ్జరీ హోటల్‌ను ఊహించుకోండి. అందులో 500 గదులు ఉన్నాయి. గది నంబర్ 304 లో ఒక అమూల్యమైన బంగారు లాకెట్ లేదా నగదు భద్రపరచబడి ఉందనుకుందాం (Variable Value). మీరు ఆ నగదును మీ జేబులో పెట్టుకుని ఊరంతా తిరగడం బరువైనది, ప్రమాదకరమైనది. దానికి బదులుగా, మీ చేతిలో "Room #304" అని రాసి ఉన్న ఒక చిన్న ప్లాస్టిక్ కీ-కార్డు (Electronic Key Card) ఉంటే సరిపోతుంది కదా!

ఆ ప్లాస్టిక్ కీ-కార్డులో బంగారం ఉండదు; కానీ బంగారం దాగి ఉన్న గది యొక్క చిరునామా (Room Address) ఉంటుంది. మీరు ఆ కార్డును తీసుకెళ్లి రూమ్ నంబర్ 304 తలుపు వద్ద స్వైప్ చేస్తే — తాళం తెరుచుకుని లోపల ఉన్న అసలైన నగదు మీ చేతికి అందుతుంది. కంప్యూటర్ సైన్స్‌లో C పాయింటర్లు సరిగ్గా ఇలాగే పనిచేస్తాయి:

  • రూమ్ లోపల ఉన్న నగదు = వేరియబుల్ విలువ (Value)
  • హోటల్ రూమ్ నంబర్ = మెమరీ అడ్రస్ (& ఆపరేటర్)
  • ప్లాస్టిక్ కీ-కార్డు = పాయింటర్ వేరియబుల్ (Pointer Variable)
  • కార్డు ద్వారా తలుపు తెరిచి లోపలి నగదును అందుకోవడం = డిరిఫరెన్సింగ్ (* ఆపరేటర్)!

పాయింటర్లపై సంపూర్ణ పట్టు సాధించిన రోజే మీరు నిజమైన C ప్రోగ్రామర్‌గా అవతరిస్తారు. ఈ పదిహేనవ అధ్యాయంలో, పాయింటర్ల అంతర్గత నిర్మాణం, పాయింటర్ అరిథ్‌మెటిక్ (Pointer Arithmetic Scale Factor), వైల్డ్ & డాంగ్లింగ్ పాయింటర్లు, మరియు సిస్టమ్ RAM మెమరీని లోతుగా శోధించే మెమరీ ఇన్‌స్పెక్టర్ టూల్‌ను సమగ్రంగా నిర్మిద్దాం!

1ఈ Chapter లో మీరు నేర్చుకునే సమగ్ర అంశాలు (Roadmap)

సిస్టమ్స్ ప్రోగ్రామింగ్, ఆపరేటింగ్ సిస్టమ్ కెర్నల్స్ మరియు హై-పెర్ఫార్మెన్స్ సాఫ్ట్‌వేర్లలో పాయింటర్లు అనేవి గుండెకాయ లాంటివి. ఈ అధ్యాయంలో కవర్ చేయబడే ప్రధానాంశాలు:

  • పాయింటర్ ప్రాథమిక నిర్వచనం: మరొక వేరియబుల్ యొక్క మెమరీ అడ్రస్‌ను భద్రపరిచే ప్రత్యేక వేరియబుల్.
  • RAM మెమరీ మోడల్ & హెక్సాడెసిమల్ అడ్రస్లు: %p ఫార్మాట్ స్పెసిఫైయర్ మరియు 64-బిట్ ఆర్కిటెక్చర్‌లో 8 బైట్ల పాయింటర్ సైజు.
  • రెండు మేజికల్ ఆపరేటర్లు: & (Address-Of) మరియు * (Dereference / Indirection).
  • పాయింటర్ల డిక్లరేషన్ & ఇనిషియలైజేషన్: int *ptr = &x; సింటాక్స్ అనాటమీ.
  • పాయింటర్ అరిథ్‌మెటిక్ రహస్యం: ptr + 1 అంటే 1 బైట్ కలపడం కాదు! డేటా టైప్ సైజు ఆధారంగా స్కేలింగ్ జరిగే విధానం.
  • పాయింటర్ సబ్‌ట్రాక్షన్ (Pointer Difference): రెండు పాయింటర్ల మధ్య తీసివేత ఫలితం ptrdiff_t.
  • సమగ్ర తులనాత్మక పట్టిక: పాయింటర్ల రకాలు (Normal, NULL, Void, Wild, Dangling).
  • జెనెరిక్ పాయింటర్లు (void* Pointers): ఏ డేటా టైప్ అడ్రస్‌నైనా పట్టుకునే సార్వత్రిక పాయింటర్ & టైప్ కాస్టింగ్.
  • ప్రమాదకరమైన 4 పాయింటర్ బగ్స్: NULL Pointer, Wild Pointer, Dangling Pointer, మరియు Memory Leaks.
  • const కీవర్డ్ మరియు పాయింటర్లు: Pointer to Const vs Const Pointer మధ్య ఉన్న కీలక వ్యత్యాసం.
  • సమగ్ర రియల్ వరల్డ్ ప్రాజెక్ట్: RAM మెమరీ హెక్స్ డంపర్ & బైట్-బై-బైట్ వేరియబుల్ ఇన్‌స్పెక్టర్.
  • బిగినర్స్ చేసే టాప్ 5 పాయింటర్ తప్పులు: * లేకుండా అసైన్‌మెంట్, అన్‌ఇనిషియలైజ్డ్ పాయింటర్ డిరిఫరెన్స్, ఆపరేటర్ ప్రిసిడెన్స్.
  • స్వీయ మూల్యాంకన క్విజ్: 5 లోతైన ప్రాక్టికల్ ప్రశ్నలు & గేట్ ఎగ్జామ్ కాన్సెప్ట్స్.
2RAM మెమరీ ఆర్కిటెక్చర్ & హెక్సాడెసిమల్ అడ్రస్లు

కంప్యూటర్ RAM (Random Access Memory) ని వేలాది చిన్న చిన్న బైట్ల గదులుగా ఊహించుకోండి. ప్రతి 1 బైట్ మెమరీ గదికి ఒక ప్రత్యేకమైన సంఖ్య ఉంటుంది, దానినే మెమరీ అడ్రస్ (Memory Address) అంటారు. కంప్యూటర్లలో ఈ చిరునామాలను చదవడానికి సులభంగా ఉండటానికి హెక్సాడెసిమల్ (Hexadecimal - Base 16: 0x...) ఫార్మాట్‌లో సూచిస్తారు.

పాయింటర్ సైజు ఆర్కిటెక్చర్ నియమం:

ఒక పాయింటర్ char* అయినా, int* అయినా, లేదా double* అయినా — అన్ని పాయింటర్ల సైజు ఒకేలా ఉంటుంది! ఎందుకంటే పాయింటర్ కేవలం మెమరీ అడ్రస్‌ను మాత్రమే నిల్వ చేస్తుంది. ఆధునిక 64-బిట్ ఆపరేటింగ్ సిస్టమ్‌లలో పాయింటర్ సైజు ఎల్లప్పుడూ సరిగ్గా 8 బైట్లు (64 bits) ఉంటుంది! పాత 32-బిట్ సిస్టమ్‌లలో 4 బైట్లు (32 bits) ఉంటుంది.

C — Memory Address & Pointer Size Demo
#include <stdio.h>

int main() {
    int age = 25;
    double salary = 75000.50;
    char grade = 'A';

    // పాయింటర్లు
    int *pAge = &age;
    double *pSalary = &salary;
    char *pGrade = &grade;

    printf("=== వేరియబుల్స్ & వాటి మెమరీ చిరునామాలు (%p ఫార్మాట్) ===\n");
    printf("age విలువ: %d        | మెమరీ అడ్రస్: %p\n", age, (void*)pAge);
    printf("salary విలువ: %.2f | మెమరీ అడ్రస్: %p\n", salary, (void*)pSalary);
    printf("grade విలువ: %c         | మెమరీ అడ్రస్: %p\n", grade, (void*)pGrade);

    printf("\n=== అన్ని రకాల పాయింటర్ల మెమరీ సైజు (sizeof) ===\n");
    printf("sizeof(int*)    = %zu బైట్లు\n", sizeof(pAge));
    printf("sizeof(double*) = %zu బైట్లు\n", sizeof(pSalary));
    printf("sizeof(char*)   = %zu బైట్లు\n", sizeof(pGrade));

    return 0;
}
3రెండు మేజికల్ ఆపరేటర్లు — & (Address-Of) మరియు * (Dereference)

పాయింటర్ల ప్రపంచంలో మొత్తం నియంత్రణ కేవలం రెండే రెండు ఆపరేటర్ల చేతుల్లో ఉంటుంది:

1. & ఆపరేటర్ (Address-Of)

ఒక సాధారణ వేరియబుల్ ముందు & ఉంచితే, అది ఆ వేరియబుల్ ఉన్న మెమరీ చిరునామాను అందిస్తుంది. (ఉదా: &x ➔ 0x7ffee1b2c458).

2. * ఆపరేటర్ (Dereference / Value-At)

ఒక పాయింటర్ వేరియబుల్ ముందు * ఉంచితే, అది ఆ చిరునామా లోపలికి నేరుగా వెళ్లి అక్కడ ఉన్న అసలైన విలువను చదవడానికి లేదా మార్చడానికి అనుమతిస్తుంది.

C — Modifying Value via Dereferencing
#include <stdio.h>

int main() {
    int target = 100;
    int *ptr = &target; // ptr ఇప్పుడు target యొక్క మెమరీ అడ్రస్ ని పట్టుకుంది

    printf("ప్రారంభ విలువ: target = %d\n", target);

    // *ptr ద్వారా అసలైన వేరియబుల్ లోని విలువను సవరిస్తున్నాం!
    *ptr = 250;

    printf("సవరించిన తర్వాత: target = %d (మారిపోయింది!)\n", target);
    printf("పాయింటర్ ద్వారా చదివిన విలువ: *ptr = %d\n", *ptr);

    return 0;
}
4పాయింటర్ అరిథ్‌మెటిక్ రహస్యం (Pointer Arithmetic Scale Factor)

చాలా మంది కొత్త ప్రోగ్రామర్లకు ఆశ్చర్యం కలిగించే అంశం ఇది: సాధారణ సంఖ్యలకు 1 కలిపితే 1 పెరుగుతుంది. కానీ పాయింటర్‌కు 1 కలిపితే (ptr + 1) అది 1 బైట్ పెరగదు!

ది స్కేల్ ఫ్యాక్టర్ ఫార్ములా (Scale Factor Formula):

పాయింటర్ అరిథ్‌మెటిక్ ఎల్లప్పుడూ ఆ పాయింటర్ పాయింట్ చేస్తున్న డేటా టైప్ పరిమాణం (Data Type Size) ఆధారంగా స్కేల్ అవుతుంది:

$$ ext{New Address} = ext{Current Address} + Big( n imes ext{sizeof(DataType)} Big)$$
  • char *p; p + 1 ➔ అడ్రస్ సరిగ్గా 1 బైట్ పెరుగుతుంది (sizeof(char) = 1).
  • int *p; p + 1 ➔ అడ్రస్ సరిగ్గా 4 బైట్లు ముందుకు దూకుతుంది (sizeof(int) = 4).
  • double *p; p + 1 ➔ అడ్రస్ సరిగ్గా 8 బైట్లు ముందుకు దూకుతుంది (sizeof(double) = 8).
C — Pointer Arithmetic Scaling Verification
#include <stdio.h>

int main() {
    int arr[3] = {10, 20, 30};
    int *p = &arr[0]; // మొదటి ఎలిమెంట్ అడ్రస్

    printf("ప్రారంభ అడ్రస్ p       = %p (arr[0] = %d)\n", (void*)p, *p);
    p = p + 1; // 4 బైట్లు ముందుకు దూకుతుంది!
    printf("p + 1 తర్వాత అడ్రస్ p  = %p (arr[1] = %d)\n", (void*)p, *p);
    p = p + 1; // మరో 4 బైట్లు ముందుకు దూకుతుంది!
    printf("p + 1 తర్వాత అడ్రస్ p  = %p (arr[2] = %d)\n", (void*)p, *p);

    return 0;
}
5పాయింటర్ల మధ్య తీసివేత & పోలికలు (Pointer Subtraction)

C లో రెండు పాయింటర్లను కూడటం (Addition: p1 + p2) చట్టవిరుద్ధం, ఎందుకంటే రెండు మెమరీ అడ్రస్‌లను కూడితే వచ్చే చిరునామాకు ఏ అర్థం ఉండదు. కానీ రెండు పాయింటర్లను తీసివేయడం (Subtraction: p2 - p1) ఖచ్చితంగా చెల్లుతుంది!

💡 పాయింటర్ తీసివేత ఫలితం: ఒకే అర్రేకు చెందిన రెండు పాయింటర్లను తీసివేస్తే, బైట్ల సంఖ్య రాదు; వాటి మధ్య ఎన్ని ఎలిమెంట్స్ ఉన్నాయో ఆ సంఖ్య వస్తుంది! C లో ఈ ఫలితాన్ని ptrdiff_t అనే స్పెషల్ ఇంటిజర్ టైప్‌లో నిల్వ చేస్తారు.
C — Pointer Subtraction (Distance Between Pointers)
#include <stdio.h>
#include <stddef.h>

int main() {
    int numbers[] = {100, 200, 300, 400, 500};

    int *ptrStart = &numbers[0]; // ఇండెక్స్ 0
    int *ptrEnd = &numbers[4];   // ఇండెక్స్ 4

    // రెండు పాయింటర్ల మధ్య దూరం
    ptrdiff_t diff = ptrEnd - ptrStart;

    printf("ptrStart అడ్రస్: %p\n", (void*)ptrStart);
    printf("ptrEnd అడ్రస్  : %p\n", (void*)ptrEnd);
    printf("రెండు పాయింటర్ల మధ్య ఎలిమెంట్స్ సంఖ్య: %td\n", diff);

    return 0;
}
6సమగ్ర తులనాత్మక పట్టిక (పాయింటర్ల రకాలు)

C ప్రోగ్రామింగ్‌లో కనిపించే వివిధ రకాల పాయింటర్ల సమగ్ర విశ్లేషణ:

పాయింటర్ రకం నిర్వచనం / అర్థం ప్రవర్తన / లక్షణం భద్రతా స్థితి
సాధారణ పాయింటర్ (Typed Pointer) నిర్దిష్ట డేటా టైప్‌కు చెందిన అడ్రస్ పట్టుకుంటుంది (ఉదా: int*). స్కేల్ ఫ్యాక్టర్ ప్రకారం అరిథ్‌మెటిక్ నడుస్తుంది. ✅ సురక్షితమైనది
NULL పాయింటర్ ఎటువంటి చెల్లుబాటు అయ్యే మెమరీకి పాయింట్ చేయదు (ptr = NULL;). సురక్షితమైన గ్రౌండింగ్; డిరిఫరెన్స్ చేయకూడదు. ✅ అత్యంత సురక్షితం
Void పాయింటర్ (Generic) ఏ డేటా టైప్ అడ్రస్‌నైనా పట్టుకునే సార్వత్రిక పాయింటర్ (void*). డిరిఫరెన్స్ చేయడానికి టైప్ కాస్టింగ్ తప్పనిసరి. ✅ జాగ్రత్తగా వాడాలి
వైల్డ్ పాయింటర్ (Wild Pointer) ఇనిషియలైజ్ చేయకుండా వదిలేసిన పాయింటర్ (Garbage address). ఏ అడ్రస్ కి వెళ్తుందో తెలీక మెమరీ క్రాష్ చేస్తుంది. 🚨 అత్యంత ప్రమాదకరం!
డాంగ్లింగ్ పాయింటర్ (Dangling) మెమరీ డిలీట్ అయిన తర్వాత కూడా ఆ పాత అడ్రస్‌నే పట్టుకున్న పాయింటర్. యూజ్-ఆఫ్టర్-ఫ్రీ (Use-After-Free) సెక్యూరిటీ బగ్. 🚨 అత్యంత ప్రమాదకరం!
7జెనెరిక్ పాయింటర్లు (void* Pointers) & టైప్ కాస్టింగ్

void* పాయింటర్ అనేది C లో ఒక సూపర్ పవర్ లాంటిది. దీనికి ఎటువంటి నిర్దిష్ట డేటా టైప్ ఉండదు. ఇది int, float, char లేదా ఏ స్ట్రక్చర్ అడ్రస్‌నైనా తనలో నిల్వ చేసుకోగలదు! సిస్టమ్ లైబ్రరీలలో మెమరీ మేనేజ్‌మెంట్ ఫంక్షన్లు (malloc, qsort) ఈ void* పైనే ఆధారపడి పనిచేస్తాయి.

⚠️ void* నియమం: కంపైలర్‌కు void* పాయింట్ చేస్తున్న డేటా సైజు ఎంతో తెలియదు కాబట్టి, దానిని నేరుగా డిరిఫరెన్స్ (*ptr) చేయలేము లేదా ptr + 1 చేయలేము! దానిని ఉపయోగించే ముందు సరైన డేటా టైప్‌లోకి టైప్ కాస్ట్ (Typecast) చేయాలి!
C — Generic void* Pointer Usage with Typecasting
#include <stdio.h>

void printValue(void *ptr, char type) {
    if (type == 'i') {
        // int* గా టైప్ కాస్ట్ చేసి డిరిఫరెన్స్ చేస్తున్నాం
        printf("ఇంటిజర్ విలువ: %d\n", *(int*)ptr);
    } else if (type == 'f') {
        // float* గా టైప్ కాస్ట్
        printf("ఫ్లోట్ విలువ: %.2f\n", *(float*)ptr);
    } else if (type == 'c') {
        // char* గా టైప్ కాస్ట్
        printf("క్యారెక్టర్ విలువ: %c\n", *(char*)ptr);
    }
}

int main() {
    int n = 42;
    float pi = 3.14159f;
    char ch = 'Z';

    printValue(&n, 'i');
    printValue(&pi, 'f');
    printValue(&ch, 'c');

    return 0;
}
8ప్రమాదకరమైన 4 పాయింటర్ బగ్స్ (Null, Wild, Dangling)

సైబర్ సెక్యూరిటీలో 70% కంటే ఎక్కువ సాఫ్ట్‌వేర్ లోపాలు తప్పుడు పాయింటర్ల వినియోగం వలనే వస్తాయి:

1. వైల్డ్ పాయింటర్ (Wild Pointer):

int *p; అని రాసి ఏ అడ్రస్ ఇవ్వకుండా వదిలేస్తే, అది గార్బేజ్ అడ్రస్‌ను పట్టుకుని ఉంటుంది. దానిని డిరిఫరెన్స్ చేస్తే సెగ్‌ఫాల్ట్ వస్తుంది. పరిష్కారం: ఎల్లప్పుడూ int *p = NULL; అని ఇనిషియలైజ్ చేయాలి.

2. డాంగ్లింగ్ పాయింటర్ (Dangling Pointer):

ఫంక్షన్ ముగిసి లోకల్ వేరియబుల్స్ నాశనమైన తర్వాత లేదా డైనమిక్ మెమరీ free() అయిన తర్వాత కూడా ఆ పాత అడ్రస్‌ను పట్టుకుని ఉండటం. పరిష్కారం: మెమరీ క్లియర్ కాగానే వెంటనే ptr = NULL; అని సెట్ చేయాలి.

9const కీవర్డ్ మరియు పాయింటర్లు (Pointer to Const vs Const Pointer)

పాయింటర్లలో const కీవర్డ్ ఎక్కడ ఉందో అనే స్థానం ఆధారంగా దాని ప్రవర్తన పూర్తిగా మారిపోతుంది. ఇంటర్వ్యూలలో అడిగే క్లాసిక్ పోలిక ఇది:

1. const int *ptr (Pointer to Constant)

పాయింటర్ పట్టుకున్న విలువను మార్చలేము! కానీ పాయింటర్ వేరొక అడ్రస్‌కి మారవచ్చు.
*ptr = 50; // ❌ ERROR
ptr = &other; // ✅ OK

2. int * const ptr (Constant Pointer)

పాయింటర్ చిరునామా స్థిరమైనది, వేరే అడ్రస్‌కి మారదు! కానీ లోపల ఉన్న విలువను మార్చవచ్చు.
*ptr = 50; // ✅ OK
ptr = &other; // ❌ ERROR

10పాయింటర్ల పాయింటర్లు (Pointer to Pointer - double**) పరిచయం

ఒక పాయింటర్ కూడా RAM లో ఉండే ఒక సాధారణ వేరియబుల్ మాత్రమే. కాబట్టి పాయింటర్‌కు కూడా ఒక మెమరీ అడ్రస్ ఉంటుంది! ఆ పాయింటర్ యొక్క అడ్రస్‌ను పట్టుకునే మరొక పాయింటర్‌ను డబుల్ పాయింటర్ (Pointer to Pointer - **) అంటారు:

C — Double Pointer (Pointer to Pointer) Concept
#include <stdio.h>

int main() {
    int value = 777;
    int *ptr1 = &value; // ptr1 -> value అడ్రస్
    int **ptr2 = &ptr1; // ptr2 -> ptr1 అడ్రస్ (డబుల్ పాయింటర్!)

    printf("value విలువ        = %d\n", value);
    printf("*ptr1 ద్వారా విలువ  = %d\n", *ptr1);
    printf("**ptr2 ద్వారా విలువ = %d (రెండుసార్లు డీరిఫరెన్స్!)\n", **ptr2);

    return 0;
}
11సమగ్ర రియల్ వరల్డ్ ప్రాజెక్ట్ — RAM మెమరీ హెక్స్ డంపర్ & బైట్ ఇన్‌స్పెక్టర్

ఇప్పటివరకు నేర్చుకున్న పాయింటర్లు, char* బైట్-బై-బైట్ ట్రావర్సల్, మరియు హెక్సాడెసిమల్ ప్రింటింగ్ ఉపయోగించి ఒక వాస్తవ RAM మెమరీ హెక్స్ డంపర్ (Raw Memory Hex Inspector Tool) ను నిర్మిద్దాం. కంప్యూటర్ RAM లో ఏదైనా వేరియబుల్ లేదా స్ట్రింగ్ అంతర్గతంగా బైట్-బై-బైట్ ఎలా నిల్వ ఉందో కళ్లారా చూడవచ్చు:

C — Raw RAM Memory Hex Dumper & Byte Inspector
#include <stdio.h>

// ఏ మెమరీ బ్లాక్‌నైనా బైట్-బై-బైట్ హెక్సాడెసిమల్‌లో ప్రింట్ చేసే ఇన్‌స్పెక్టర్
void dumpMemory(const void *startAddr, size_t numBytes) {
    // 1 బైట్ చొప్పున చదవడానికి unsigned char* కి టైప్ కాస్ట్ చేస్తున్నాం
    const unsigned char *bytePtr = (const unsigned char*)startAddr;

    printf("====================================================\n");
    printf("   RAM మెమరీ ఇన్‌స్పెక్టర్ (Raw Byte Hex Dumper)\n");
    printf("====================================================\n");
    printf("ప్రారంభ మెమరీ అడ్రస్: %p  | మొత్తం బైట్లు: %zu\n", startAddr, numBytes);
    printf("----------------------------------------------------\n");
    printf("ఆఫ్‌సెట్ | మెమరీ అడ్రస్        | హెక్స్ విలువ | క్యారెక్టర్\n");
    printf("----------------------------------------------------\n");

    for (size_t i = 0; i < numBytes; i++) {
        unsigned char b = bytePtr[i];
        // ముద్రించదగిన అక్షరమా కాదా అని చెక్ చేయడం
        char printable = (b >= 32 && b <= 126) ? b : '.';

        printf("+%02zu    | %p | 0x%02X       | '%c'\n",
               i, (void*)&bytePtr[i], b, printable);
    }
    printf("====================================================\n\n");
}

int main() {
    // 1. ఒక ఇంటిజర్ వేరియబుల్ మెమరీని పరీక్షిద్దాం (Little-Endian ఆర్కిటెక్చర్)
    int secretCode = 0x12345678;
    printf("1. ఇంటిజర్ వేరియబుల్ RAM లేఅవుట్ (0x12345678):\n");
    dumpMemory(&secretCode, sizeof(secretCode));

    // 2. ఒక స్ట్రింగ్ మెమరీ లేఅవుట్‌ను పరీక్షిద్దాం
    char message[] = "Mana C 2026";
    printf("2. స్ట్రింగ్ వేరియబుల్ RAM లేఅవుట్ ("Mana C 2026"):\n");
    dumpMemory(message, sizeof(message));

    return 0;
}
12సాధారణంగా బిగినర్స్ చేసే టాప్ 5 పాయింటర్ తప్పులు
1. అన్‌ఇనిషియలైజ్డ్ పాయింటర్‌ను డిరిఫరెన్స్ చేయడం:
int *p; *p = 10; అని రాస్తే గార్బేజ్ అడ్రస్‌లోకి రాతలు రాసి ఆపరేటింగ్ సిస్టమ్ సెగ్మెంటేషన్ ఫాల్ట్ ఇస్తుంది. ఎల్లప్పుడూ ఒక వేరియబుల్ అడ్రస్ లేదా NULL ఇవ్వాలి.
2. *ptr బదులు ptr కు విలువ అసైన్ చేయడం:
p = 10; అని రాస్తే పాయింటర్ అడ్రస్ 10 అయిపోతుంది! లోపల ఉన్న విలువను మార్చడానికి కచ్చితంగా *p = 10; అని రాయాలి.
3. void* ను నేరుగా డిరిఫరెన్స్ చేయడానికి ప్రయత్నించడం:
void *p; printf("%d", *p); కంపైలర్ ఎర్రర్ ఇస్తుంది. కచ్చితంగా *(int*)p అని టైప్ కాస్ట్ చేయాలి.
4. ఆపరేటర్ ప్రిసిడెన్స్ కన్‌ఫ్యూజన్ ((*ptr)++ vs *ptr++):
*ptr++ రాస్తే పాయింటర్ అడ్రస్ పెరుగుతుంది; లోపల విలువను పెంచడానికి (*ptr)++ అని బ్రాకెట్లు వాడాలి.
5. వేర్వేరు డేటా టైప్స్ పాయింటర్లను తారుమారు చేయడం:
double d = 5.5; int *p = &d; అని రాస్తే 4 బైట్లు మాత్రమే చదివి డేటా పూర్తిగా కరప్ట్ అవుతుంది!
13స్వీయ మూల్యాంకన క్విజ్ & మీరే స్వయంగా Try చేయండి!

ఈ పాఠంలోని లోతైన అంశాలను క్రింది 5 ప్రాక్టికల్ ప్రశ్నల ద్వారా పరీక్షించుకోండి:

❓ ప్రశ్న 1: 64-బిట్ కంప్యూటర్‌లో char* మరియు double* పాయింటర్ల మెమరీ సైజు ఎంత ఉంటుంది?
సమాధానం: రెండింటి సైజు ఖచ్చితంగా 8 బైట్లు (64 bits) మాత్రమే ఉంటుంది! పాయింటర్ కేవలం మెమరీ అడ్రస్‌ను మాత్రమే నిల్వ చేస్తుంది కాబట్టి డేటా టైప్‌తో సంబంధం లేకుండా అన్ని పాయింటర్ల సైజు సమానంగా ఉంటుంది.
❓ ప్రశ్న 2: int *ptr ఉన్నప్పుడు 'ptr + 1' చేస్తే అడ్రస్ ఎన్ని బైట్లు పెరుగుతుంది?
సమాధానం: సరిగ్గా 4 బైట్లు పెరుగుతుంది! పాయింటర్ అరిథ్‌మెటిక్ ఆ డేటా టైప్ సైజు ఆధారంగా స్కేల్ అవుతుంది (sizeof(int) = 4).
❓ ప్రశ్న 3: void* పాయింటర్‌ను నేరుగా డిరిఫరెన్స్ చేయవచ్చా?
సమాధానం: చేయకూడదు (Compile Error)! కంపైలర్‌కు ఆ మెమరీ లొకేషన్ సైజు ఎంతో తెలియదు కాబట్టి, దానిని సరైన టైప్‌లోకి (ఉదా: *(int*)ptr) టైప్ కాస్ట్ చేసిన తర్వాతే డిరిఫరెన్స్ చేయాలి.
❓ ప్రశ్న 4: వైల్డ్ పాయింటర్ (Wild Pointer) మరియు డాంగ్లింగ్ పాయింటర్ (Dangling Pointer) మధ్య తేడా ఏమిటి?
సమాధానం: ఇనిషియలైజ్ చేయకుండా వదిలేసిన పాయింటర్‌ను వైల్డ్ పాయింటర్ అంటారు. మెమరీ తొలగించబడిన తర్వాత కూడా ఆ పాత చిరునామానే పట్టుకుని ఉండే పాయింటర్‌ను డాంగ్లింగ్ పాయింటర్ అంటారు.
❓ ప్రశ్న 5: 'const int *p' మరియు 'int * const p' ల మధ్య తేడా ఏమిటి?
సమాధానం: const int *p లో విలువను మార్చలేము (రీడ్-ఓన్లీ డేటా); int * const p లో చిరునామాను మార్చలేము (స్థిరమైన పాయింటర్).
🚀 RAM మెమరీ హెక్స్ డంపర్‌ను మన ఆన్‌లైన్ C కంపైలర్‌లో రన్ చేయండి!

పైన వివరించిన RAM మెమరీ హెక్స్ ఇన్‌స్పెక్టర్ మరియు పాయింటర్ అరిథ్‌మెటిక్ కోడ్‌లను మన ఆన్‌లైన్ C కంపైలర్‌లో ఓపెన్ చేసి స్వయంగా రన్ చేయండి. మీ వేరియబుల్స్ మెమరీలో బైట్-బై-బైట్ ఎలా స్టోర్ అయ్యాయో కళ్లారా చూడండి!

👉 Our Compiler లో C Compiler try చేయండి

📌 అధ్యాయ సారాంశం (Quick Summary):

  • పాయింటర్లు: మెమరీ చిరునామాలను నిల్వ చేసే ప్రత్యేక వేరియబుల్స్ (64-బిట్ లో 8 బైట్లు).
  • & ఆపరేటర్: వేరియబుల్ ఉన్న మెమరీ అడ్రస్‌ను అందిస్తుంది.
  • * ఆపరేటర్: పాయింటర్ అడ్రస్ లోపలికి వెళ్లి విలువను చదవడానికి/మార్చడానికి డిరిఫరెన్స్ చేస్తుంది.
  • స్కేల్ ఫ్యాక్టర్: ptr + 1 అంటే 1 బైట్ కాదు, ఆ డేటా టైప్ పరిమాణం మేర ముందుకు దూకుతుంది.
  • void*: ఏ డేటా టైప్ నైనా పట్టుకునే సార్వత్రిక జెనెరిక్ పాయింటర్.
తర్వాతి అధ్యాయంలో (Chapter 16 — Phase 04 ముగింపు): పాయింటర్లు మరియు అర్రేల మధ్య ఉన్న అవినాభావ సంబంధం — పాయింటర్స్ విత్ అర్రేస్, డబుల్ పాయింటర్లు (char**), కమాండ్ లైన్ ఆర్గుమెంట్స్ (argc, argv) మరియు ఫంక్షన్ పాయింటర్లు గురించి అత్యంత లోతుగా నేర్చుకుందాం!
← Prev: 14. స్ట్రింగ్స్ & <string.h> Next: 16. పాయింటర్లు & అర్రేస్ →
OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on GCC 13+ / Clang 17 runtime · 2026 Academic Edition