Day 19: dynamic memory management

Posted by Horizon88 on Wed, 16 Feb 2022 13:03:41 +0100

Today's learning effect is unsatisfactory. I interrupt from time to time and only learn a little content. I use the structure to make the address book and optimize the address book with the knowledge of dynamic memory allocation. It seems that one mind and two uses are also a skill worth mastering.

1. Why is there dynamic memory allocation

The memory development methods we have mastered include:

int val = 20;//Open up four bytes in stack space
char arr[10] = {0};//Open up 10 bytes of continuous space on the stack space

However, the above-mentioned way of opening up space has two characteristics:

1. The space development size is fixed.

2. When the array is declared, the length of the array must be specified, and the memory it needs will be allocated at compile time. But the demand for space is not just the above situation. Sometimes the size of the space we need can only be known when the program is running, so the way of opening up space during array compilation cannot be satisfied.

At this time, you can only try dynamic storage development.

2. Introduction of dynamic memory function

2.1 malloc and free

C language provides a function of dynamic memory development:

void* malloc (size_t size);

This function requests a continuously available space from memory and returns a pointer to this space.

If the development is successful, it returns a pointer to the developed space.

If the development fails, a NULL pointer is returned, so the return value of malloc must be checked.

The type of the return value is void *, so the malloc function does not know the type of open space, which is determined by the user when using it.

If the parameter size is 0, malloc's behavior is standard and undefined, depending on the compiler.

C language provides another function free, which is specially used for dynamic memory release and recovery. The function prototype is as follows:

void free (void* ptr);

The free function is used to free the dynamic memory.

If the space pointed to by the parameter ptr is not dynamically opened up, the behavior of the free function is undefined.

If the parameter ptr is a NULL pointer, the function does nothing.

malloc and free are both declared in stdlib H header file. They need to appear in pairs.

for instance:

#include <stdlib.h>
#include <stdio.h>
int main()
{
 //Code 1
 int num = 0;
 scanf("%d", &num);
 int arr[num] = {0};
 
 //Code 2
 int* ptr = NULL;
 ptr = (int*)malloc(num*sizeof(int));
 if(NULL != ptr)//Judge whether ptr pointer is null
 {
 int i = 0;
 for(i=0; i<num; i++)
 {
     *(ptr + i) = 0;      
 }
 }
 free(ptr);//Free the dynamic memory pointed by ptr
 ptr = NULL;
 return 0;
}

2.2 calloc

C language also provides a function called calloc, which is also used for dynamic memory allocation. The prototype is as follows:

void* calloc (size_t num, size_t size);

The function is to open up a space for num size elements, and initialize each byte of the space to 0.

The difference between calloc and malloc is that calloc initializes each byte of the requested space to all zeros before returning the address.

for instance:

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

int main()

{

 int *p = (int*)calloc(10, sizeof(int));

 if(NULL != p)

 {

 //Use space
 }

 free(p);

 p = NULL;

 return 0;

}

2.3 realloc

The emergence of realloc function makes dynamic memory management more flexible.

Sometimes we find that the space applied for in the past is too small, and sometimes we feel that the space applied for is too large. In order to make the memory reasonable, we will flexibly adjust the size of the memory. Then realloc function can adjust the size of dynamic memory.

The function prototype is as follows:

void* realloc (void* ptr, size_t size);

ptr is the memory address to be adjusted

New size after size adjustment

The return value is the adjusted starting position of memory.

This function will also move the data in the original memory to a new space on the basis of adjusting the size of the original memory space.

realloc adjusts memory space in two ways:

Case 1: there is enough space after the original space

Case 2: there is not enough space after the original space

Case 1 when it is case 1, if you want to expand the memory, you can directly add space after the original memory, and the data of the original space will not change.

In case 2, when there is not enough space after the original space, the expansion method is to find another continuous space of appropriate size on the heap space. In this way, the function returns a new memory address.

Due to the above two cases, we should pay attention to the use of realloc function. for instance:

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

int main()

{

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

 if(ptr != NULL)

 {

     //Business processing

 }

 else

 {

     exit(EXIT_FAILURE);    

 }

 //Expansion capacity

 //Code 1

 ptr = (int*)realloc(ptr, 1000);//Is this ok? (what happens if the application fails?)

 //Receive directly. If the application fails, the null pointer will be returned and the original address will not be found
 

 //Code 2 

 int*p = NULL;

 p = realloc(ptr, 1000);

 if(p != NULL)

 {

 ptr = p;

 }

 //Business processing

 free(ptr);

 return 0;

}

Topics: C