Back to C Programming
2026-07-157 min read

Dynamic Memory Allocation for Arrays

Learn Dynamic Memory Allocation for Arrays step by step with clear examples and exercises.

Why This Matters

Welcome to this engaging and practical guide on dynamic memory allocation for arrays in C programming! In this lesson, we will delve into the fascinating world of managing memory dynamically for arrays, a skill that is essential for writing efficient and robust programs. By the end of this tutorial, you'll be equipped with the knowledge and tools to tackle real-world coding challenges and avoid common pitfalls.

Why This Matters

Dynamic memory allocation plays a crucial role in C programming as it allows us to create arrays of varying sizes at runtime. This flexibility is vital for developing applications that can handle data of different sizes, making them more efficient and versatile. Understanding dynamic memory allocation for arrays will also help you prepare for job interviews, coding competitions, and real-world programming scenarios where the size of the input data may not be known in advance.

Prerequisites

Before diving into dynamic memory allocation for arrays, it is essential to have a solid understanding of the following concepts:

  1. Variables and Data Types: Understanding how variables are declared and their associated data types (e.g., int, char, float) is fundamental to working with arrays in C.
  2. Arrays: Familiarity with fixed-size arrays, array declarations, and accessing array elements is crucial for grasping dynamic memory allocation.
  3. Pointers: Pointers are a powerful tool that enables us to manipulate memory directly. Understanding how pointers work and how they can be used to create dynamic arrays is essential.
  4. Memory Allocation Functions: Familiarity with the standard library functions for memory allocation, such as malloc(), calloc(), free(), and realloc(), is necessary for working with dynamic memory in C.

Core Concept

Dynamic memory allocation for arrays in C involves using pointers to allocate and manage memory at runtime. The key functions we'll focus on are:

  1. malloc(): This function dynamically allocates an uninitialized block of memory of the specified size, returning a pointer to the first byte of the allocated memory.
  2. calloc(): Similar to malloc(), but initializes the allocated memory to zero.
  3. free(): Frees the previously allocated memory, making it available for future allocation.
  4. realloc(): Resizes an existing block of memory and moves the contents to a new location if necessary.

Creating a Dynamic Array with malloc()

Let's create a simple dynamic array using malloc().

#include <stdio.h>
#include <stdlib.h>

int main() {
int n, i;
int *arr; // Declare a pointer to an integer array

printf("Enter the number of elements: ");
scanf("%d", &n);

arr = (int *) malloc(n * sizeof(int)); // Allocate memory for n integers

if (arr == NULL) { // Check if memory allocation was successful
printf("Memory allocation failed!\n");
return 1;
}

printf("Enter %d integers:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", arr + i); // Access elements using pointer arithmetic
}

printf("\nThe entered integers are:\n");
for (i = 0; i < n; i++) {
printf("%d ", *(arr + i)); // Print elements using pointer dereference
}

free(arr); // Free the allocated memory when done
return 0;
}

In this example, we first declare a pointer arr to an integer array. We then prompt the user for the number of elements and allocate memory for them using malloc(). After that, we read the integers from the user, store them in the dynamic array, and print them out. Finally, we free the allocated memory using free().

Using calloc() to Initialize Dynamic Arrays

To create a dynamically-sized initialized array, use calloc() instead of malloc(). The function initializes the memory to zero, which can be useful for arrays of boolean values or when working with structures.

#include <stdio.h>
#include <stdlib.h>

int main() {
int n, i;
int *arr; // Declare a pointer to an integer array

printf("Enter the number of elements: ");
scanf("%d", &n);

arr = (int *) calloc(n, sizeof(int)); // Allocate and initialize memory for n integers

if (arr == NULL) { // Check if memory allocation was successful
printf("Memory allocation failed!\n");
return 1;
}

// Set all elements to a default value (e.g., 0 or 1)
for (i = 0; i < n; i++) {
arr[i] = 0;
}

printf("\nThe initialized integers are:\n");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]); // Print the initialized values
}

free(arr); // Free the allocated memory when done
return 0;
}

In this example, we use calloc() to allocate and initialize memory for an array of integers. We then set all elements to a default value (zero in this case) using pointer arithmetic.

Worked Example

Let's create a program that dynamically allocates an array to store the frequencies of words in a given input string.

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

#define MAX_WORDS 100

int main() {
char str[100];
int word_freq[MAX_WORDS] = {0}; // Initialize an array to store word frequencies
int num_words = 0;
char current_word[50];

printf("Enter a string: ");
fgets(str, sizeof(str), stdin);

// Split the input string into words and count their frequencies
for (int i = 0; i < strlen(str); i++) {
if (isspace(str[i])) {
if (num_words < MAX_WORDS) {
current_word[i - strlen(current_word)] = '\0'; // Terminate the current word
word_freq[(int) strtoul(current_word, NULL, 10)]++; // Increment the frequency of the current word
num_words++;
}
} else {
if (num_words < MAX_WORDS) {
current_word[strlen(current_word)] = str[i];
current_word[strlen(current_word) + 1] = '\0'; // Reserve space for the null terminator
}
}
}

// Print the word frequencies
printf("\nWord Frequencies:\n");
for (int i = 0; i < num_words; i++) {
printf("%d: %s\n", word_freq[i], current_word);
current_word[strlen(current_word)] = '\0'; // Reset the current word for the next iteration
}

return 0;
}

In this example, we use malloc() to dynamically allocate an array of integers (word_freq) to store the frequencies of words. We then read a string from the user, split it into words using spaces as delimiters, and count their frequencies by incrementing the appropriate elements in the dynamic array.

Common Mistakes

  1. Forgetting to check for memory allocation failure: Always check if malloc() or calloc() returns a null pointer before using the allocated memory.
  2. Leaking memory: Make sure to free the dynamically-allocated memory when it is no longer needed, using the free() function.
  3. Using incorrect size arguments in malloc(): Ensure that the size argument passed to malloc() or calloc() matches the size of the data type you're allocating memory for.
  4. Accessing out-of-bounds memory: Be careful not to access elements outside the bounds of your dynamically-allocated arrays, as this can lead to undefined behavior and security vulnerabilities.
  5. Not initializing dynamic arrays with calloc(): If you need an initialized array, use calloc() instead of malloc().
  6. Forgotten null terminators in character arrays: When working with dynamically-allocated character arrays, don't forget to allocate space for the null terminator (\0) and ensure that it is properly set.

Practice Questions

  1. Write a program that dynamically allocates an array to store the names of 10 students and their corresponding scores in a school exam. Prompt the user to enter the student names and scores, and then print out the average score for each student.
  2. Write a program that dynamically allocates an array to store the frequencies of vowels in a given input string. Print out the most frequently used vowel and its frequency.
  3. Write a program that reads a file line by line, dynamically allocates memory for each line, and stores the lines in a linked list. After reading all the lines, print out the contents of the linked list.

FAQ

  1. Why should I use dynamic memory allocation instead of fixed-size arrays? Dynamic memory allocation allows us to create arrays of varying sizes at runtime, making our programs more flexible and efficient in handling data of different sizes.
  2. What is the difference between malloc() and calloc()? Both malloc() and calloc() dynamically allocate memory, but calloc() initializes the allocated memory to zero.
  3. How do I find the size of an array that has been dynamically allocated using malloc() or calloc()? You can use the sizeof() operator to determine the size of a dynamically-allocated array. However, keep in mind that the size is typically stored in a variable, not directly accessible as with fixed-size arrays.
  4. What happens if I free() memory that was not allocated using malloc(), calloc(), or realloc()? Attempting to free memory that was not properly allocated can lead to undefined behavior and potential security vulnerabilities.
  5. Is it safe to use dynamic memory allocation in embedded systems or real-time applications? Dynamic memory allocation can be problematic in environments with limited resources, as it may result in fragmented memory and increased overhead. In such cases, fixed-size arrays or other memory management techniques may be more appropriate.