Back to C Programming
2026-07-158 min read

C - Chain of Pointers

Learn C - Chain of Pointers step by step with clear examples and exercises.

Why This Matters

In this comprehensive lesson on C programming, we delve into the intriguing world of pointers and explore an essential concept known as a "Chain of Pointers." Understanding this topic is crucial for mastering dynamic memory allocation, data structures, and efficient memory management. This knowledge will not only prepare you for coding interviews but also equip you with valuable skills for real-world programming scenarios. Let's embark on this exciting journey!

Prerequisites

To fully grasp the Chain of Pointers concept, you should have a solid understanding of the following topics:

  1. C Basics: Variables, Data Types, Operators, Control Structures, Functions
  2. Pointers in C: Declaring pointers, Pointer Arithmetics, Dereferencing, and Memory Allocation
  3. Arrays in C: Understanding Array Declaration, Accessing Array Elements, and Passing Arrays to Functions
  4. Structures and Pointers to Structures: Declaring structures, Accessing Structure Members, and Pointer Arithmetic with Structures
  5. File I/O: Reading from and Writing to Files in C

Core Concept

A Chain of Pointers is a collection of memory locations that are linked together using pointers. Each pointer stores the address of the next memory location in the chain, creating a sequential list of memory locations. This structure allows for dynamic memory allocation and flexible data management.

!Chain of Pointers Diagram

In the diagram above, we have a Chain of Pointers with four elements. Each ptr variable points to the next element in the chain, forming a linear list.

Declaring a Chain of Pointers

To declare a Chain of Pointers, you first need to define an array of pointers:

int *ptrArray[5]; // An array of 5 integer pointers
char **strPtrArray[3]; // An array of 3 character pointer arrays
struct Student *studentPtrArray[10]; // An array of 10 pointers to Student structures
FILE **filePtrArray[2]; // An array of 2 FILE pointers

You can then assign each pointer in the array a value using the & operator:

int arr[] = {1, 2, 3, 4, 5};
ptrArray[0] = &arr[0]; // First element of the array
ptrArray[1] = &arr[1]; // Second element of the array
ptrArray[2] = &arr[2]; // Third element of the array
ptrArray[3] = &arr[3]; // Fourth element of the array
ptrArray[4] = NULL; // Last element is set to NULL, indicating the end of the chain

For structures:

struct Student {
char name[50];
int age;
};

struct Student students[] = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 28}
};
studentPtrArray[0] = &students[0]; // First element of the array
studentPtrArray[1] = &students[1]; // Second element of the array
studentPtrArray[2] = &students[2]; // Third element of the array

Accessing Elements in a Chain of Pointers

To access an element in the chain, you can follow the pointers until you reach the desired memory location:

printf("%d ", *ptrArray[0]); // Output: 1 (First element)
printf("%s ", studentPtrArray[0]->name); // Output: Alice (First Student structure)

Advantages of a Chain of Pointers

  • Dynamic Memory Allocation: You can easily add or remove elements from the chain as needed, without modifying the source code.
  • Flexible Data Management: Each pointer in the chain can point to different data types (e.g., integers, strings, structures), making it versatile for various applications.
  • Memory Efficiency: Unlike using arrays, you only need to store pointers instead of actual data values, saving memory space.
  • Improved Performance: Accessing elements in a Chain of Pointers can be faster than accessing elements in an array, especially when dealing with large datasets.

Worked Example

Let's create several programs that demonstrate the Chain of Pointers concept for different data types:

Chain of Integers

#include <stdio.h>

int main() {
int arr[] = {1, 2, 3, 4, 5};
int *ptrArray[5];

// Initialize the chain of pointers
for (int i = 0; i < 5; ++i) {
ptrArray[i] = &arr[i];
}

// Print each element in the chain
for (int i = 0; i < 5; ++i) {
printf("%d ", *ptrArray[i]);
}

return 0;
}

Chain of Character Arrays

#include <stdio.h>
#include <string.h>

int main() {
char strArr[][50] = {"Apple", "Banana", "Cherry"};
char **strPtrArray[3];

// Initialize the chain of pointers
for (int i = 0; i < 3; ++i) {
strPtrArray[i] = &strArr[i];
}

// Print each element in the chain
for (int i = 0; i < 3; ++i) {
printf("%s\n", *strPtrArray[i]);
}

return 0;
}

Chain of Student Structures

#include <stdio.h>

struct Student {
char name[50];
int age;
};

int main() {
struct Student students[] = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 28}
};
struct Student *studentPtrArray[3];

// Initialize the chain of pointers
for (int i = 0; i < 3; ++i) {
studentPtrArray[i] = &students[i];
}

// Print each element in the chain
for (int i = 0; i < 3; ++i) {
printf("Name: %s, Age: %d\n", studentPtrArray[i]->name, studentPtrArray[i]->age);
}

return 0;
}

Chain of FILE Pointers

#include <stdio.h>

int main() {
char fileName1[] = "file1.txt";
char fileName2[] = "file2.txt";
FILE *filePtrArray[2];

// Open the files and initialize the chain of pointers
for (int i = 0; i < 2; ++i) {
filePtrArray[i] = fopen(fileName[i], "r");
}

// Read from each file in the chain
for (int i = 0; i < 2; ++i) {
char ch;
while ((ch = fgetc(filePtrArray[i])) != EOF) {
printf("%c", ch);
}
}

// Close the files in the chain
for (int i = 0; i < 2; ++i) {
fclose(filePtrArray[i]);
}

return 0;
}

Common Mistakes

  1. Forgetting to initialize the last pointer in the chain: Always set the last pointer to NULL or an appropriate value to indicate the end of the chain.
  2. Accessing out-of-bounds memory: Be careful not to access elements beyond the bounds of your array or chain of pointers, as this can lead to segmentation faults and other runtime errors.
  3. Incorrect pointer arithmetic: Remember that when you increment a pointer, it moves to the next memory location of its data type. For example, incrementing an int pointer will move it to the next int.
  4. Misunderstanding dynamic memory allocation: When adding or removing elements from a chain of pointers, be sure to update all the pointers accordingly to maintain the proper order and avoid dangling pointers.
  5. Memory leaks: Ensure that you properly deallocate memory when it's no longer needed, especially when using dynamically allocated memory.
  6. Confusing pointers and references: In some programming languages (e.g., C++), there is a distinction between pointers and references. Be sure to understand the differences in your chosen language.
  7. Using uninitialized pointers: Always initialize your pointers before using them, as uninitialized pointers can lead to undefined behavior.
  8. Not handling NULL pointers properly: When dealing with chains of pointers that may contain NULL values, be sure to check for them and handle them appropriately in your code.
  9. Incorrectly freeing dynamically allocated memory: Be careful when freeing dynamically allocated memory, as freeing the wrong memory or multiple times can lead to memory leaks and other issues.
  10. Not properly closing files in a chain of FILE pointers: Always close each file in the chain after reading its contents to ensure that resources are released correctly.

Practice Questions

  1. Write a program that creates a Chain of Pointers for an array of strings and prints each string in the chain, allowing users to input new strings and add them to the chain dynamically.
  2. Implement a function that adds a new element to the end of a given Chain of Pointers. The function should take the data type and value as arguments and dynamically allocate memory for the new element before adding it to the chain.
  3. Create a Chain of Pointers for a dynamically allocated array, and implement a function that removes the last element from the chain and frees its memory.
  4. Write a program that creates a circular linked list using pointers, allowing users to insert new nodes at the end of the list dynamically.
  5. Implement a function that searches for a specific value in a Chain of Pointers and returns the index of the first occurrence, or -1 if not found.
  6. Create a program that reads data from multiple files (stored in a chain of FILE pointers) and merges their contents into a single output file.
  7. Write a function that sorts a Chain of Pointers containing Student structures based on the age field.
  8. Implement a function that reverses the order of elements in a given Chain of Pointers.
  9. Write a program that creates a Chain of Pointers for an array of integers and finds the maximum, minimum, and average values in the chain.
  10. Create a program that simulates a simple database using a Chain of Pointers to Student structures, allowing users to search for students by name or age.

FAQ

A: Yes! Creating a circular linked list using pointers involves setting the last pointer in the chain to point back to the first element, forming a loop.

Q: Is it possible to have multiple chains of pointers sharing common elements?

A: Yes, by having multiple chains of pointers pointing to the same memory locations, you can create interconnected data structures called linked lists or graphs.

Q: How can I check if a given pointer is part of a specific chain of pointers?

A: You can traverse the chain of pointers starting from the first element and compare each pointer with the given pointer until you find a match or exhaust the chain. If the given pointer does not match any pointer in the chain, it's not part of that particular chain.

Q: How do I handle dynamic memory allocation when adding elements to a Chain of Pointers?

A: You can use functions like malloc() and realloc() to dynamically allocate memory for new elements. Be sure to update all pointers in the chain accordingly to maintain the proper order.

Q: What are some common data structures that can be implemented using a Chain of Pointers?

A: Some common data structures that can be implemented using a Chain of Pointers include singly and doubly linked lists, stacks, queues, trees, and graphs.

Q: How do I properly deallocate memory when using a Chain of Pointers with dynamically allocated memory?

A: You should use free() to deallocate the memory for each element in the chain when it's no longer needed. Be sure to handle cases where the chain may be empty or contain NULL pointers.

Q: Can I use a Chain of Pointers to implement a hash table?

A: Yes, you can use a Chain of Pointers as an array of linked lists in a hash table implementation. Each key-value pair is stored in a separate linked list based on its hash value.