Skip to content

Pointers

Pointer: Variable storing the address of another variable.

  • Every variable is stored at a specific memory location, identified by an address.
  • A pointer stores this address, not the actual value. Pointer Arithmetic:
  • Incrementing a pointer moves to the next memory location of the data type it points to. There is total 4 arithmetic operators that can be used on pointer: Pointers support arithmetic operations like:
    • ++ → Move to next memory location
    • -- → Move to previous memory location
    • + → Add an integer to a pointer
    • - → Subtract an integer from a pointer
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30};
int *p = arr;
printf("%d ", *p);
p++;
printf("%d ", *p);
return 0;
}

Types of Pointers:

  • Null Pointer: Points to nothing, int *ptr = NULL;
  • Void Pointer: Can point to any data type, void *ptr;
  • Dangling Pointer: Points to a memory location that has been freed.

Usage Of Pointers:

  • Accessing array elements
  • Dynamic memory allocation
  • Passing arguments to functions by reference
  • Implementing data structures like linked lists and trees
  • Accessing and manipulating memory directly

Dereferencing:

  • Accessing the value stored at the memory address held by the pointer.
  • Use the asterisk (*) operator to dereference a pointer.

Significance in Memory Management:

  • Pointers allow direct access to memory, which can lead to more efficient and flexible code.
  • Enable dynamic memory allocation (malloc, calloc, free).
  • Facilitate the creation of complex data structures.

Common Pitfalls:

  • Dangling Pointers: Using pointers that point to freed memory.
  • Null Pointers: Dereferencing null pointers leading to crashes.
  • Memory Leaks: Not freeing dynamically allocated memory.
  • Pointer Arithmetic Errors: Miscalculations leading to invalid memory access.
  • Buffer Overflows: Accessing memory beyond allocated limits.

Pass by Value:

  • Copies the actual value of an argument into the formal parameter of the function.
  • Changes made to the parameter inside the function do not affect the actual argument.
#include <stdio.h>
void changeValue(int x) {
x = 50;
printf("Inside function: x = %d\n", x);
}
int main() {
int a = 10;
printf("Before function call: a = %d\n", a);
changeValue(a);
printf("After function call: a = %d\n", a);
return 0;
}

Pass by Reference (using pointers):

  • Copies the address of an argument into the formal parameter of the function.
  • Changes made to the parameter affect the actual argument.
#include <stdio.h>
void changeValue(int *x) {
*x = 50;
printf("Inside function: *x = %d\n", *x);
}
int main() {
int a = 10;
printf("Before function call: a = %d\n", a);
changeValue(&a);
printf("After function call: a = %d\n", a);
return 0;
}
#include <stdio.h>
int main()
{
printf("Lets learn about pointers\n");
int a=76;
int *ptra = &a;
int *ptr2 = NULL;
printf("The address of pointer to a is %p\n", &ptra);
printf("The address of a is %p\n", &a);
printf("The address of a is %p\n", ptra);
printf("The address of some garbage is %p\n", ptr2);
printf("The value of a is %d\n", *ptra);
printf("The value of a is %d\n", a);
return 0;
}