[C language] dynamic memory distribution

Posted by CaptainChainsaw on Wed, 29 Dec 2021 04:13:47 +0100

preface

This blog post is only for me to summarize and learn the knowledge of dynamic memory allocation in C language. In the summary process, I refer to many blogs.

Reference blog:

https://www.cnblogs.com/ericling/p/11746972.html

https://blog.csdn.net/MarcoAsensio/article/details/85937002

summary

An array is a collection of a fixed number of values that cannot be changed after declaring the size of the array. Sometimes, the array size may not be enough, so it needs to be dynamically expanded. To solve this problem, you can manually allocate memory at run time. This is called dynamic memory allocation in C programming.

In C language, memory is divided into four storage areas, stack, heap, static storage area and code area. Heap memory is a memory block that is applied when needed and released when not needed. It is completed by programmers. Today, let's discuss the library functions for dynamically allocating heap memory. These library functions are contained in the header file < stdlib h> Yes.

The library functions involved in dynamic memory allocation are

  • malloc()
  • calloc()
  • realloc()
  • free()

1.malloc function

malloc's full name is memory allocation, which is called dynamic memory allocation in Chinese. It is used to apply for a continuous memory block area of specified size and return the address of the allocated memory area in void * type. When the specific location of memory cannot be known, dynamic memory allocation is required to bind the real memory space.

The prototype of the function is extern void *malloc(unsigned int num_bytes);

Next, we write a code to randomly allocate 40 bytes of storage space with malloc function and print the address of the storage space,

Syntax of malloc()

ptr = (castType*) malloc(size);

Example:

ptr = (int*) malloc(100 * sizeof(float));

The above statement allocates 400 bytes of memory. This is because the size of float is 4 bytes. Moreover, the pointer ptr stores the memory address of the first byte in the allocated memory.

If memory cannot be allocated, the expression produces a NULL pointer.

Then we find this memory address,


It is found that 40 bytes of uninitialized memory space has been generated. The malloc function is used to open up the heap memory space of the specified size.

2.calloc function

Allocate n consecutive spaces with length of size in the dynamic storage area of memory, and the function returns a pointer to the allocation start address; If the allocation is unsuccessful, NULL is returned.

The prototype of the function is void *calloc(size_t n, size_t size);

The name "calloc" represents continuous allocation.

The malloc() function allocates memory but does not initialize memory. The calloc() function allocates memory and initializes all bits to zero.

Similarly, we write a piece of code, use the calloc function to randomly allocate 40 bytes of storage space, and print out the address of the storage space,

Syntax of calloc()

ptr = (castType*)calloc(n, size);

Example:

ptr = (float*) calloc(25, sizeof(float));

The above statement allocates contiguous space in memory for 25 elements of type float.

Then we find this memory address,

Then we were surprised to find that the 40 byte heap memory opened up by the calloc function has been initialized to 0, which is the difference between malloc and calloc functions.

3.free()

Using calloc() or malloc() does not release the dynamically allocated memory created separately. You must explicitly use free() to free space.

Syntax of free()

free(ptr);

This statement frees the space ptr allocated in the memory pointed to by.

// Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n, i, *ptr, sum = 0;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    ptr = (int*) malloc(n * sizeof(int));
 
    // if memory cannot be allocated
    if(ptr == NULL)                     
    {
        printf("Error! memory not allocated.");
        exit(0);
    }
    printf("Enter elements: ");
    for(i = 0; i < n; ++i)
    {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }
    printf("Sum = %d", sum);
  
    // deallocating the memory
    free(ptr);
    return 0;
}

Here, we have dynamically allocated memory for n numbers
Example 2: calloc() and free()

// Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n, i, *ptr, sum = 0;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    ptr = (int*) calloc(n, sizeof(int));
    if(ptr == NULL)
    {
        printf("Error! memory not allocated.");
        exit(0);
    }
    printf("Enter elements: ");
    for(i = 0; i < n; ++i)
    {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }
    printf("Sum = %d", sum);
    free(ptr);
    return 0;
}

4.realloc function

First judge whether the current pointer has enough continuous space. If so, expand mem_address points to the address of, and mem_address returns. If there is not enough space, allocate space according to the size specified by newsize, copy the original data from beginning to end to the newly allocated memory area, and then release the original mem_address refers to the memory area (Note: the original pointer is automatically released without using free), and returns the first address of the newly allocated memory area, that is, the address of the re allocated memory block.

The prototype of the function is extern void *realloc(void *mem_address, unsigned int newsize);

Let's write a piece of code. First apply for 40 bytes of heap memory with malloc function, and then expand it with realloc function. If we only expand 4 bytes,

If the dynamically allocated memory is insufficient or exceeds the requirements, you can use this realloc() function to change the size of the previously allocated memory.

Syntax of realloc()

ptr = realloc(ptr, x);

Here, the ptr is redistributed with a new size x.

Example 3: realloc ()

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *ptr, i , n1, n2;
    printf("Enter size: ");
    scanf("%d", &n1);
    ptr = (int*) malloc(n1 * sizeof(int));
    printf("Addresses of previously allocated memory: ");
    for(i = 0; i < n1; ++i)
         printf("%u\n",ptr + i);
    printf("\nEnter the new size: ");
    scanf("%d", &n2);
    // rellocating the memory
    ptr = realloc(ptr, n2 * sizeof(int));
    printf("Addresses of newly allocated memory: ");
    for(i = 0; i < n2; ++i)
         printf("%u\n", ptr + i);
  
    free(ptr);
    return 0;
}

When running the program, the output is:

Input size: 2
 Address of previously allocated memory: 26855472
26855476

Enter new size: 4
 Newly allocated memory address: 26855472
26855476
26855480
26855484

We will find that the addresses of the two memories are the same, but if we amplify 400 bytes,

We will find that the addresses of the two memories are different, which means that before using the realloc function, we will first judge whether the memory behind the original memory is enough. If it is enough, it will be directly connected to the original memory for expansion. If it is not enough, we will first copy the contents of the original memory to a new memory, then release the original memory, and then expand it behind the new memory, This is the characteristic of realloc function.

Note: search of memory address content: VS, debugging -- > window -- > memory

summary

  1. malloc
    malloc dynamically allocates memory without initialization. If memory cannot be allocated, NULL is returned.
int n, *ptr = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
  1. calloc

calloc dynamically allocates memory, initializes all bit s to 0, and returns NULL if memory cannot be allocated

int n, *ptr = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) calloc(n, sizeof(int));

Free free memory

free(ptr);

Realloc realloc reallocate memory

ptr = realloc(ptr, n * sizeof(int));

Topics: C data structure memory management malloc