Padhai Search notes and questions

C ProgrammingUnit 93 min read

Pointers in C: Declaration, Arithmetic, Arrays and Functions

Unit 9 of BSc CSIT C Programming: what a pointer is, the & and * operators, pointer arithmetic, pointers with arrays, call by reference and dynamic memory allocation, with runnable examples.

Key points

  • A pointer is a variable that stores the memory address of another variable.
  • The & operator gives a variable's address, and the * operator reads the value at an address (dereferencing).
  • Pointer arithmetic moves by whole elements, not bytes, so a[i] is the same as *(a + i).
  • Passing addresses (call by reference) lets a function change the caller's variables, as in swap(&x, &y).
  • malloc, calloc and realloc allocate memory at run time. Check the result for NULL and free every block you allocate.

A pointer is a variable that stores the memory address of another variable. Pointers let you pass variables to functions by reference, work efficiently with arrays and strings, and allocate memory at run time.

Declaring and using a pointer

#include <stdio.h>

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

    printf("x   = %d\n", x);
    printf("&x  = %p\n", (void *)&x);
    printf("p   = %p\n", (void *)p);
    printf("*p  = %d\n", *p);   /* value at that address: 10 */

    *p = 25;              /* changes x through the pointer */
    printf("x   = %d\n", x);    /* 25 */
    return 0;
}
  • & is the address-of operator.
  • * in a declaration makes a pointer. In an expression it dereferences the pointer, which means it reads the value at the address.

Pointer arithmetic

Adding 1 to a pointer moves it forward by one element, not one byte. If p is an int * and an int is 4 bytes, then p + 1 is 4 bytes further on.

Allowed: adding or subtracting an integer, subtracting two pointers into the same array, and comparing pointers. Not allowed: adding two pointers, or multiplying and dividing pointers.

Pointers and arrays

An array's name is the address of its first element, so a[i] is the same as *(a + i).

int a[5] = {2, 4, 6, 8, 10};
int *p = a;
for (int i = 0; i < 5; i++)
    printf("%d ", *(p + i));

Call by value vs call by reference

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}
/* call: swap(&x, &y); */

With call by value, the function gets copies, so the caller's variables do not change. Passing addresses (call by reference) lets the function change the caller's variables. This is a common long question.

Dynamic memory allocation

Functions from <stdlib.h>:

Function Purpose
malloc(size) Allocates size bytes. The memory is not initialised.
calloc(n, size) Allocates n elements and sets every byte to zero.
realloc(ptr, size) Resizes a block that was allocated earlier.
free(ptr) Releases the memory.
int n, *arr;
scanf("%d", &n);
arr = malloc(n * sizeof *arr);
if (arr == NULL) { printf("Out of memory\n"); return 1; }
/* ... use arr[0] .. arr[n-1] ... */
free(arr);

Always check the result for NULL, and free every block you allocate.

Common mistakes

  • Uninitialised pointer: dereferencing a pointer before giving it an address.
  • Dangling pointer: using memory after free.
  • Memory leak: losing the only pointer to allocated memory without freeing it.

Exam tip

Expect questions like "What is a pointer? Explain pointer arithmetic with an example" and "Write a program to sort n numbers using dynamic memory allocation." Always include a short working program.

Based on the TU BSc CSIT syllabus for C Programming (CSC110), unit 9.