C Program: Array Summation Using Pointers

This program reads N integers into a dynamically allocated array and computes their sum using pointer arithmetic instead of array subscript notation. Understanding the equivalence between *(a + i) and a[i] is fundamental to C — both produce identical machine code. The program also demonstrates malloc() and free() for runtime-sized arrays.

The original post used conio.h, malloc.h (a non-standard Turbo C header), and void main(). It never freed the allocated memory. This rewrite uses the standard <stdlib.h>, checks malloc’s return value, uses correct pointer arithmetic, and always calls free().

C Program: Array Sum Using Pointer Arithmetic

/* Sum of array elements using pointer arithmetic
 * Compile: gcc -ansi -Wall -Wextra array_sum_ptr.c -o array_sum_ptr */
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int *a;
    int i, n, sum = 0;

    printf("Enter number of elements: ");
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("Invalid input.\n");
        return 1;
    }

    a = (int *)malloc((size_t)n * sizeof(int));
    if (a == NULL) {
        fprintf(stderr, "Memory allocation failed.\n");
        return 1;
    }

    printf("Enter %d integers:\n", n);
    for (i = 0; i < n; i++) {
        if (scanf("%d", a + i) != 1) {   /* a+i is the address of element i */
            printf("Invalid input.\n");
            free(a);
            return 1;
        }
    }

    /* Access elements via pointer arithmetic */
    printf("\nArray elements: ");
    for (i = 0; i < n; i++)
        printf("%d ", *(a + i));   /* *(a+i) is identical to a[i] */
    printf("\n");

    for (i = 0; i < n; i++)
        sum += *(a + i);

    printf("Sum = %d\n", sum);

    free(a);
    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra array_sum_ptr.c -o array_sum_ptr
./array_sum_ptr

Sample Output

Enter number of elements: 5
Enter 5 integers:
10 20 30 40 50

Array elements: 10 20 30 40 50
Sum = 150

Array Subscript vs Pointer Arithmetic

Notation Equivalent Meaning
a[i] *(a + i) Value at address a + i*sizeof(int)
&a[i] a + i Address of element i
scanf("%d", &a[i]) scanf("%d", a + i) Read an int into element i
a[0] *a First element (i=0 → a+0 → a)

Code Explanation

  • malloc((size_t)n * sizeof(int)) — allocates a contiguous block of memory large enough for n integers. The cast to size_t ensures unsigned multiplication — without it, a very large n could overflow a signed int before being passed to malloc. sizeof(int) gives the correct byte size for the platform (4 bytes on 32-bit and 64-bit systems).
  • Check malloc return value for NULL — if the system is out of memory, malloc returns NULL. Attempting to write to a NULL pointer is undefined behavior and typically causes a segfault. Always check: if (a == NULL) before using the pointer.
  • a + i as an address — in C, pointer arithmetic automatically accounts for the element size. a + 1 advances by sizeof(int) bytes, not by 1 byte. So a + i points to the i-th element, and scanf("%d", a + i) reads an int directly into that position — equivalent to scanf("%d", &a[i]).
  • *(a + i) vs a[i] — both compile to identical instructions. The C standard defines a[i] as syntactic sugar for *(a + i). The subscript form is more readable; the pointer form makes the memory model explicit. Professional C code uses subscript notation for arrays and pointer arithmetic when traversing linked structures.
  • free(a) at the end — every malloc() call must be paired with exactly one free(). Forgetting free is a memory leak — the allocated block is never returned to the system. In this small program the OS reclaims it on exit, but in long-running programs or embedded systems, memory leaks are serious bugs.
  • Non-standard headers in original: malloc.h — Turbo C/BorlandC had a separate malloc.h header. In standard C, malloc(), free(), realloc(), and calloc() are declared in <stdlib.h>. Never include malloc.h — it does not exist on GCC/Clang.

What This Program Teaches

  • a[i] is *(a + i) — always — this equivalence is defined by the C standard. Knowing this makes it clear why pointers and arrays are so closely related in C, and why array names decay to pointers in most contexts.
  • Dynamic allocation for runtime-sized arrays — in C89/C90, array sizes must be compile-time constants (int a[10]). To read N at runtime and allocate exactly N elements, you must use malloc. C99 introduced variable-length arrays (VLAs), but malloc is preferred for large allocations or when lifetime must extend beyond the current scope.
  • Always free what you malloc — a common mnemonic: every malloc needs a free. Tools like Valgrind detect memory leaks. On embedded systems without virtual memory, a leak in a long-running loop will exhaust physical RAM and crash the system.

Related Programs

Recommended book:
The C Programming Language — Kernighan & Ritchie (India) |
(US)
 | 
C Programming: A Modern Approach — K.N. King (India) |
(US)

Practice what you learned: C Aptitude Questions — or try our C Programming Quiz App on Android.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>