[C Language] Dynamic allocation and release of memory

Personal homepage: Xiu Xiu Ye

Column: C language

Operating environment:Visual Studio 2022

?

Table of Contents

What is dynamic allocation of memory?

Memory dynamic allocation function

malloc()

calloc()

realloc()

Dynamic memory release function

free()

Common dynamic memory errors

1. Dereference operation of NULL pointer

2. Out-of-bounds access to dynamically opened space

3. Use free release for non-dynamically allocated memory

4. Use free to release a part of dynamically allocated memory

5. Release the same dynamic memory multiple times

6. Dynamically allocated memory and forget to release it

Conclusion


What is dynamic allocation of memory?

To know what dynamic allocation of memory is, you must first understand how memory is divided in the computer:

As shown in the figure, the memory area is roughly divided into the following areas:

?

  • Stack area (growing downward) (stack): automatically allocated and released by the compiler, storing: local variables, formal parameters, return values.
  • Heap area (growing upward) (heap): memory is allocated and released by the programmer. By calling functions: malloc(), calloc(), realloc() and free().
  • Global (static) area: uninitialized global/static area (.bass) and initialized global/static area (.data).
  • Constant area (.rodata): string “ABCD”, etc.

  • Code area (.text): stores the program code

The way we used memory in the past was, for example, creating a variable:

int a=10;

At this time, the variable is stored in the stack area and is automatically allocated by the compiler.

Another example is if we create an array, such as:

int arr[10]={0};

At this time, the contents of the array are still stored in the stack area, and are allocated space for storage or destroyed by the compiler.

This kind of memory usage has two characteristics:

  1. The memory space allocation size is fixed.
  2. When an array is declared, the length of the array must be specified, and the memory it requires is allocated at compile time.

This characteristic means that we cannot allocate storage space at any time during the running of the program, nor cannot release or discard unnecessary storage space. In order to meet the above requirements If required, we need to use dynamic allocation of memory.

Dynamic memory allocation function

The two functions used to allocate storage space are the malloc() and calloc() functions, and the function used to change the allocated space is the realloc() function, listed below Information about these functions:

malloc()

malloc
Header file #include
Format void * malloc(size_t size);
Function Allocate storage space for an object of size bytes. The initial value in this storage space is uncertain< /strong>
Return value If the allocation is successful, a pointer to the beginning of the allocated space is returned. Pointer; if the allocation fails, a null pointer is returned

If you want to know more information about the malloc() function, such as the settings of malloc() function parameters, the setting of return values, and the specific usage of the malloc() function, etc. You can move here:

[C Language] Detailed explanation of malloc() function (dynamic memory allocation function) icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article /details/133971625?spm=1001.2014.3001.5502

calloc()

calloc
Header file #include
Format void * calloc(size_t num,size_t size);
Function Allocate storage space for num objects of size bytes. All objects in the space Bits will be initialized to 0
Return value If the allocation is successful, a pointer to Pointer to the beginning of the allocated space; if the allocation fails, a null pointer is returned

If you want to know more information about the calloc() function, such as the setting of the calloc() function parameters, the setting of the return value, and the specific use of the calloc() function, etc. You can move here:

[C Language] Detailed explanation of calloc() function (dynamic memory allocation function) icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article /details/133975677

realloc()

realloc
Header file #include
Format void * realloc(void* ptr , size_t size);
Function Change the size of the allocated space pointed to by ptr and reallocate it to size
Return value If the allocation is successful, a pointer to the beginning of the allocated space is returned; If the allocation fails, a null pointer is returned

If you want to learn more information about the realloc() function, such as the setting of realloc() function parameters, the setting of the return value, and the specific use of the realloc() function, etc. You can move here:

[C Language] Detailed explanation of realloc() function (dynamic memory allocation function) icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article /details/133975646

Dynamic memory release function

free()

free
Header file #include
Format void * free(void* ptr);
Function Release the space pointed to by ptr so that this space can continue to be used for subsequent dynamic allocation. When ptr is a null pointer, no operation is performed. In addition, when the actual parameters are the same as before When the pointers returned by malloc(), calloc(), and realloc() are inconsistent, or when the space pointed by ptr has been released by calling free() or realloc(), it will be treated as undefined.
Return value None

If you want to know more about the free() function, such as the setting of the free() function parameters, the setting of the return value, and the specific use of the free() function, etc. , you can move here:

[C language] Detailed explanation of free() function (dynamic memory release function) icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article /details/133975657

Common dynamic memory errors

1. Dereference operation of NULL pointer

Here we first introduce to you a method of printing error codes:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<stdio.h>

int main()
{
    int* p = (int*)malloc(INT_MAX);
    if (p == NULL) //If the development fails, print an error
    {
        //A way to print the cause of the error
        printf("%s\\
", strerror(errno));
    }
    else
    {
        printf("Development successful\\
");
        //You can use the p pointer to operate this space normally.
    }

    return 0;
}

Let’s test this code in the vs compiler:

You can see that strerror successfully printed the error message.

Let’s look at this code again:

void test()
{
    int *p = (int *)malloc(INT_MAX);

    *p = 20;//If the value of p is NULL, there will be a problem

    free(p);
}

It can be seen from the definition of malloc() that when malloc encounters a situation where there is not enough space to open, it will fail to open and return a null pointer.

And when we fail to check the result of the malloc() function, it is likely to lead to the following situation:

Therefore, in order to prevent the dereference operation of the null pointer when using the dynamic memory allocation function, we should first check its return value after each use of the dynamic memory allocation function.

2. Out-of-bounds access to dynamically allocated space

The following code:

void test()
{
    int i = 0;
    int* p = (int*)malloc(10 * sizeof(int));
    if (NULL == p)
    {
        //A way to print the cause of the error
        printf("%s\\
", strerror(errno));
    }
    for (i = 0; i <= 10; i + + )
    {
        *(p + i) = i;//When i is 10, it will cause out-of-bounds access
    }
    free(p);
}

Test this code in vs2022:

As you can see, the compiler directly reports an error “Heap corruption detected“. An error like thiswhether it means that the stack area is damaged or the heap area is damaged means that< strong>An out-of-bounds access occurred on the stack or heap.

Therefore, when using dynamic memory to open up space, we must be extra careful not to have out-of-bounds access problems.

3. Use free release for non-dynamically allocated memory

Because p is allocated to the stack area by the compiler, it does not belong to the heap area, so free release cannot be used.

void test()
{
    int a = 10;
    int *p = &a;
    free(p); //p is not dynamically opened and cannot be released
}

Use vs2022 to test:

As you can see, this error caused the program to go wrong.

The error “Breakpoint instruction has been executed” in the picture is because undefined illegal behavior occurred during the execution of the code.

4. Use free to release a part of dynamically allocated memory

The following code:

void test()
{
    int *p = (int *)malloc(100);
    p + + ;
    free(p); //p no longer points to the starting location of dynamic memory
}

Test it in vs2022:

As you can see, this error caused the program to terminate abnormally.

5. Release the same dynamic memory multiple times

The following code:

void test()
{
    int *p = (int *)malloc(100);
    free(p);
    free(p); //repeated release
}

Test in vs2022:

As you can see, this error caused a program error.

Here are two tips to prevent repeated release:

  • Try to follow the principle of who develops and who recycles
  • Set the original dynamically allocated pointer to NULL immediately after free.

6. Dynamically allocated memory and forget to release it

The following code:

void test()
{
    int *p = (int *)malloc(100);
    if(NULL != p)
    {
        *p = 20;
    }
    //No release!
}

int main()
{
    test();
}

If the dynamically allocated memory is forgotten to be released, the program will not report an error, but it will cause a memory leak!

Forgetting to release dynamically allocated space that is no longer used can cause memory leaks.

Memory leak: If the dynamically allocated memory is not released, then these memories will continue to occupy system resources, resulting in memory leaks. Memory leaks can cause programs to slow down or even crash.

therefore:

The dynamically opened space must be released and released correctly!

The dynamically opened space must be released and released correctly!

The dynamically opened space must be released and released correctly!

Conclusion

I hope this article on the dynamic allocation of memory can be helpful to everyone. Welcome to leave a message or private message to communicate with me.

The sea of learning is vast, and I am also struggling! Follow me, everyone will learn and make progress together!

Recommended related articles

[C Language] Detailed explanation of malloc() function (dynamic memory allocation function)

[C Language] Detailed explanation of realloc() function (dynamic memory allocation function)

[C language] Detailed explanation of calloc() function (dynamic memory allocation function)

[C language] Detailed explanation of free() function (dynamic memory release function)

[C language] memcpy() function

[Data structure practical project] Detailed explanation of data structure sequence table in C language (with complete running code)

[Practical Programming Tips] Don’t want to fix bugs? Beginners must learn to use the error reporting function assert! (detailed explanation of assertion function)

?

Mind map of library functions related to dynamic memory development in C language:

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Algorithm skill tree Home page Overview 57067 people are learning the system