Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding Pointers in C Programming

Tech 3

Introduction to Pointers

Pointers are a fundamental concept in C programming, often presenting a significant challenge for beginners due to their complexity and unfamiliarity.

What Are Pointers?

Consider a real-world analogy: a dormitory building with rooms numbered 1 to 100, each housing eight students. If a teacher needs to locate specific students, they must first find the room number (addresss) before accessing the students (data). This process mirrors how a CPU uses pointers to access memory locations.

Key concepts:

  1. Pointer = Address
  2. Creating a variable in C involves requesting memory space.

Defining Pointer Variables

int main() {
    int value = 0;
    int* ptr = &value;
    return 0;
}

Explanation:

  • *: Pointer declaration
  • int: Data type stored at the memory location pointed to
  • ptr: Pointer variable name
  • &: Address-of operator, which retrieves the memory address of value

This code stores the address of value in ptr. You can modify the original variable through dereferencing or change the address stored in ptr.

Dereferencing Pointers

Concept: The dereference operator * allows access to the memory location pointed to by a pointer, enabilng modificasion of the stored value.

Pointer Variable Size

Key points:

  1. Pointer size depends on the compiler's architecture, not the pointer type.
    • 64-bit systems: 8 bytes
    • 32-bit systems: 4 bytes
  2. Pointer type determines:
    • Number of bytes accessed during dereferencing
    • Step size for pointer arithmetic (e.g., +1)
    • Example: char* moves 1 byte, int* moves 4 bytes

Void Pointers

Concept: void* pointers are generic pointers that cannot be directly dereferenced or used in pointer arithmetic. They require explicit type casting before use.

#include <assert.h>

int main() {
    int data = 1;
    int* ptr = &data;
    assert(ptr != NULL); // Ensure pointer is not null before dereferencing
    return 0;
}

Note: Null pointers also cannot be dereferenced; always verify a pointer is not null before use.

Const-Modified Pointers

  1. const before *: Prevents modification of the pointed-to value but allows changing the pointer's address.
  2. const after *: Allows modification of the pointed-to value but prevents chnaging the pointer's address.

Pointer Arithmetic

Pointer ± Integer

Since array elements are stored contiguously in memory, knowing the first element's address enables access to all elements.

Example:

int arr[5] = {10, 20, 30, 40, 50};
int* p = arr;
printf("%d", *(p + 2)); // Outputs 30

If p were char*, +1 would move only 1 byte, potentially causing incorrect access for int arrays.

Pointer - Pointer

Subtracting two pointers yields the number of elements between them, useful for operations like string length calculation.

int arr[5] = {0};
int* start = &arr[0];
int* end = &arr[4];
printf("%ld", end - start); // Outputs 4

Wild Pointers

Causes of Wild Pointers

  1. Uninitialized Pointers:
int main() {
    int* p; // Uninitialized, contains garbage value
    *p = 20; // Undefined behavior
    return 0;
}
  1. Out-of-Bounds Access:
int main() {
    int arr[10] = {0};
    int* p = arr;
    for (int i = 0; i <= 11; i++) {
        *(p++) = i; // Becomes wild pointer when exceeding array bounds
    }
    return 0;
}
  1. Pointer to Freed Memory:
int* test() {
    int local = 100;
    return &local; // Returns address of local variable that goes out of scope
}

int main() {
    int* p = test(); // p becomes wild pointer
    printf("%d\n", *p); // Undefined behavior
    return 0;
}

Pass-by-Address in Function Calls

Concept: For simple value operations, pass-by-value suffices:

int add(int x, int y) {
    return x + y;
}

int main() {
    int a = 5, b = 4;
    int result = add(a, b);
    return 0;
}

Pass-by-addres allows functions to modify variables in the calling function by passing their addresses:

void modify(int* ptr) {
    *ptr = 100;
}

int main() {
    int value = 5;
    modify(&value); // value becomes 100
    return 0;
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.