Dynamic memory allocation: malloc, calloc, and realloc

Keywords: C C++ Memory Leak

1, Why dynamic memory allocation

When we declare an array in c language, we must first specify the size of an array, but in practice, we often can't know the size of the array we set in advance. For example, suppose we want to count the data of all students in a class, but the number of students in different classes may be different. In this case, we usually declare a large array, This ensures that it can accommodate the most possible elements.

Dynamic memory allocation avoids this problem by allocating memory to the data to be saved during the operation of the program.

2, Correlation function

The following related function declarations are in the header file of #include < stdlib. H >.

1. malloc function

The c function library provides two functions, malloc and free, which are respectively used to perform dynamic memory allocation and release. Here, it must be borne in mind that who applies for release in c language. If you use malloc function to apply for a certain space in your program, you must release it at the end of program operation.

The two functions are declared as follows:

void* malloc(size_t size); // Enter the size of the space you want to apply for
void free(void pointer);   // Pass in a pointer to the space you want to free

It should be noted that malloc obtains a continuous memory. If the memory pool is empty or the currently available memory is not enough, malloc will return a NULL pointer when applying for space. Therefore, we need to check malloc when applying to ensure that our application for memory allocation is successful.

Note that the memory requested by malloc must be initialized manually.

2. calloc function

The function is declared as follows:

void* calloc(size_t num_elements   // Number of elements requiring memory application
             size_t element_size)  // Memory size of element type to be applied

The calloc function is also used to allocate memory, but unlike malloc, calloc initializes pointers to memory to 0 before returning them. In addition, we can also see from the incoming parameters declared by the function. Calloc calculates the total memory size to be allocated according to the number of required elements and bytes of each element.

3. realloc function

void realloc(void *ptr,           // Pointer to original memory
             size_t new_size)     // Current memory size to allocate

Realloc function is used to modify the size of a previously allocated memory block. If the memory block is expanded, the original contents of the memory block will still be saved. The newly added memory will be added to the back of the original memory block, and the newly allocated memory will not be initialized; If you shrink a memory block, the tail memory of the memory block will be removed and the rest will remain. If the size of the original memory block cannot be changed, realloc will reallocate a correct memory block and copy the contents of the original memory block to the new block.

3, Code example

The function of a function is to create an array with a length of n, store any value less than n, return it to the main function and output it.

The code is as follows:

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

int* create_random_array(int n){ // Generates an array of random numbers
    srand(time(NULL));
    int *arr = malloc(n*sizeof(int));
    for(int i=0; i<n; ++i){
        arr[i] = rand()%n;
    }
    return arr;
}
void print_array(int* arr, int n){// Print array
    for(int i=0; i<n; i++){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int main(){
    int n;
    scanf("%d", &n);
    int* arr = create_random_array(n);
    printf("malloc => arr: ");
    print_array(arr, n);

    int* arr2 = calloc(n, sizeof(int));
    printf("calloc => arr2: ");
    print_array(arr2, n);
    
    arr = realloc(arr, 2*n*sizeof(int));
    for(int i=n; i<2*n; ++i){
        arr[i] = 0;
    }
    printf("realloc => arr: ");
    print_array(arr, 2*n);
    
    free(arr);
    free(arr2);
    arr = NULL;
    arr2 = NULL;

}

The operation result is:

4, Summary of warnings for incorrect use of dynamically allocated memory

  1. Do not check whether the pointer returned from malloc function is' NULL ';
  2. Accessing areas outside the dynamically allocated memory;
  3. Pass a pointer to the free function that is not returned by the malloc function
  4. Dynamic memory is accessed after it is freed.

Note:
If the allocated memory is not released after use, it will cause memory leakage. If we do not release the memory in time after dynamically applying for memory, the available space in the memory pool becomes less and less, and finally we have nothing, so that the program cannot be executed.

Posted by mnetsys on Tue, 30 Nov 2021 02:51:57 -0800