Dynamically allocate memory

This is an introduction to how to dynamically allocate memory in C language. In C, dynamic memory allocation is required to represent data structures whose size is known only at run time.

The C language array is a static array that is sized at compile time. String literals are also sized at compile time.

Practical programming often requires dynamic data whose size is known only at run time. If you want to determine the number of elements at runtime, you need to create a dynamic array, and to create a dynamic string that you want to determine the number of characters at runtime, you basically need to remember dynamic memory allocation.

Dynamically allocate memory

To allocate memory dynamically, malloc defined in the stdlib.h header Use the function or calloc function.

In the introduction to C language with C99, we recommend the calloc function that initializes the memory area to 0. I will explain how to allocate memory dynamically using the calloc function.

Let's allocate memory dynamically with the calloc function. char type (1 byte), allocate a memory area of ​​length 4.

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

int main (void) {
  // Dynamic memory allocation
  int32_t capacity = 4;
  char * bytes = calloc (sizeof (char), capacity);
  
  // Use the reserved memory area. Be careful not to exceed the reserved area. Initially it is zero initialized.
  bytes [2] = 5;
  printf("%d%d%d\n", bytes [0], bytes [1], bytes [2]);
}

This is the output result.

0 0 5

Next, try to secure a memory area of ​​3 length with int32_t type (4 bytes). 4x3 reserves 12 bytes of memory.

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

int main (void) {
  // Dynamic memory allocation
  int32_t capacity = 3;
  int32_t * nums = calloc (sizeof (int32_t), capacity);
  
  // Use the reserved memory area. Be careful not to exceed the reserved area. Initially it is zero initialized.
  nums [2] = 7;
  printf("%d%d%d\n", nums [0], nums [1], nums [2]);
}

This is the output result.

0 0 7

Release the reserved memory

The reserved memory area is released by using the free function when it is no longer needed.

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

int main (void) {
  // Dynamic memory allocation
  int32_t capacity = 4;
  char * bytes = calloc (sizeof (char), capacity);
  
  // process
  
  // Release with free when you no longer need it
  free (bytes);
}

It cannot be said unconditionally when the reserved memory area becomes unnecessary. If the data is required from the beginning to the end of the program, release it just before the program ends.

Also, in the program, the memory area is repeatedly secured, and when it is no longer needed, it is released when it is no longer needed.

For example, suppose an HTTP request is sent, the HTTP request data is represented by a structure, and the HTTP request data is no longer needed after processing. In such a case, the memory is allocated when the HTTP request is sent, and the memory is released when it is no longer needed.

Creating a dynamic array

As a sample of dynamic memory allocation, let's dynamically allocate memory and create a dynamic array to which elements can be added. The data type of the element should be int32_t type. The length of the first memory area of ​​the array should be 4.

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

int main (void) {
  // Length of memory area of ​​array
  int32_t capacity = 4;
  
  // Last index of the array
  int32_t last_index = 0;
  
  // Dynamically allocate memory
  int32_t * nums = calloc (capacity, sizeof (int32_t));
  
  // Add elements to the array
  nums [last_index] = 3;
  last_index ++;
  
  // Add elements to the array
  nums [last_index] = 8;
  last_index ++;
  
  // Add elements to the array
  nums [last_index] = 7;
  last_index ++;
  
  // Add elements to the array
  nums [last_index] = 15;
  last_index ++;
  
  // last_index is 4, which exceeds the capacity of the array.
  
  // Expand the memory area
  // Reserve a new memory area that is twice the size
  int32_t new_capacity = capacity * 2;
  int32_t * new_nums = calloc (new_capacity, sizeof (int32_t));
  
  // Copy the memory area from the current one to the new one
  memcpy (new_nums, nums, capacity * sizeof (int32_t));
  
  // Free the current memory area
  free (nums);
  
  // Set the new memory area to the current memory area
  nums = new_nums;
  
  // Set to NULL so as not to use it incorrectly
  new_nums = NULL;
  
  // Now you can add new elements
  
  // Add elements to the array
  nums [last_index] = 20;
  last_index ++;
  
  for (int32_t i = 0; i <last_index; i ++) {
    printf("%d\n", nums [i]);
  }
}

This is the output result.

3
8
7
15
20

If this can be expressed by for statement and function, You will be able to create your own dynamic array library.

I wrote it as a dynamic array, but if you look closely at the implementation later, it looks like it represents a stack (Oh).

Associated Information