C language: dynamic memory (an article on dynamic memory!)

Table of contents

learning target: 

Why does dynamic memory allocation exist 

Dynamic memory functions:

1. malloc and free

2. calloc

3. realloc

Common dynamic memory errors:

1. Dereference operation on NULL pointer

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

3. Use free to release non-dynamically allocated memory

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

5. Multiple releases of the same dynamic memory

6. Dynamically open up memory and forget to release it (memory leak)

Program memory allocation:

Flexible array:

Use of flexible arrays:

Advantages of flexible arrays:

 The above is the analysis of personal learning insights and learning, welcome everyone to discuss in the comment area!

Thanks for the one-click three-connection guys! Thanks for the one-click three-connection guys! Thanks for the one-click three-connection guys!


learning target: 

Why does dynamic memory allocation exist?
Introduction to dynamic memory functions:
1、malloc;
2、free;
3、calloc;
4、realloc;
5. Common dynamic memory errors;
6. Memory development;
6. Flexible array.

Why does dynamic memory allocation exist 

The general way of opening up space has two characteristics:

1. The size of space development is fixed.
2. When the array is declared, the length of the array must be specified, and the memory it needs is allocated at compile time
        Due to the need for space, it is not just the case above. Sometimes the size of the space we need can only be known when the program is running , and the way of creating space when compiling the array is not enough. At this time, you can only try dynamic storage and development.

Dynamic memory functions:

1. malloc and free

void*  malloc (size_t size);
        
         size: The size of the memory block in bytes. is an unsigned integer. size_t
1.1 This function applies for a continuous available space from the memory and returns a pointer to this space.
1.2 If the allocation is successful , a pointer to the allocated space will be returned .
      If the opening fails , a NULL pointer is returned , so the return value of malloc must be checked.
1.3 The type of the return value is void* , so the malloc function does not know the type of the opened space, and the user can decide by himself when using it.
1.4 If the parameter size is 0 , the behavior of malloc is undefined by the standard and depends on the compiler.

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

void  free (void* ptr);
        
         ptr: A pointer to a previously allocated block of memory.
1.1 The free function is used to release the dynamically allocated memory .
1.2 If the space pointed to by the parameter ptr is not dynamically opened, the behavior of the free function is undefined.
1.3 If the parameter ptr is a NULL pointer , the function does nothing .
1.4 Both malloc and free are declared in the stdlib.h header file.
#include <stdio.h>

int main()
{
     //静态代码
     int num = 0;
     scanf("%d", &num);
     int arr[num] = {0};
     //动态代码
     int* ptr = NULL;
     ptr = (int*)malloc(num*sizeof(int));
     //判断ptr指针是否为空
     if(NULL != ptr)
     {
         int i = 0;
         for(i=0; i<num; i++)
         {
             *(ptr+i) = 0;
         }
     }
     //释放ptr所指向的动态内存
     free(ptr);
     ptr = NULL;
     return 0;
}

2. calloc

void* calloc (size_t num, size_t size);
        
        num: The number of elements to allocate.
        size: The size of each element.
2.1 The function of the function is to open up a space for num elements of size size, and initialize each byte of the space to 0.
2.2 The difference from the function malloc is that calloc will initialize each byte of the requested space to all 0s before returning the address .

#include <stdio.h>
#include <stdlib.h>
int main()
{
     int *p = (int*)calloc(10, sizeof(int));
     if(NULL != p)
     {
         //使用这块空间
     }
     free(p);
     p = NULL;
     return 0;
}

3.realloc

        Sometimes we find that the space we applied for in the past is too small, and sometimes we feel that the space we applied for is too large. In order to make the memory reasonable, we must flexible adjustments to the size of the memory . Then the realloc function can adjust the size of the dynamically allocated memory.
void*  realloc (void* ptr, size_t size);
        
       ptr: A pointer to a previously allocated block of memory. Or this can be a null pointer , in which case a new block will be allocated (as if called).
        size: The new size of the memory block in bytes. is an unsigned integer. size_t
3.1 ptr is the memory address to be adjusted.
3.2 New size after size adjustment.
3.3 The return value is the adjusted memory starting position.
3.4  On the basis of adjusting the size of the original memory space, this function will also move the data in the original memory to the new space.
3.5 There are two situations when realloc adjusts the memory space :
        Case 1 : There is enough space after the original space
                To expand the memory, directly add space after the original memory, and the data in the original space will not change.
        Case 2 : There is not enough space after the original space
When there is not enough space                after the original space , the expansion method is: find another continuous space of suitable size on the heap space to use. This function returns a new memory address.

#include <stdio.h>
int main()
{
     int *ptr = (int*)malloc(100);
     if(ptr != NULL)
     {
         //业务处理
     }
     else
     {
         exit(EXIT_FAILURE);    
     }
     //扩展容量
     //ptr = (int*)realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?)
 
     int*p = NULL;
     p = realloc(ptr, 1000);
     if(p != NULL)
     {
         ptr = p;
     }
     
     free(ptr);
     return 0;
}

Common dynamic memory errors:

1. Dereference operation on NULL pointer

void test()
{
     int *p = (int *)malloc(INT_MAX/4);
     *p = 20;//如果p的值是NULL,就会有问题
     free(p);
}

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

void test()
{
     int i = 0;
     int *p = (int *)malloc(10*sizeof(int));
     if(NULL == p)
     {
         exit(EXIT_FAILURE);
     }
     for(i=0; i<=10; i++)
     {
         *(p+i) = i;//当i是10的时候越界访问
     }
     free(p);
}

3. Use free to release non-dynamically allocated memory

void test()
{
     int a = 10;
     int *p = &a;
     free(p);//ok?
}

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

void test()
{
     int *p = (int *)malloc(100);
     p++;
     free(p);//p不再指向动态内存的起始位置
}

5. Multiple releases of the same dynamic memory

void test()
{
     int *p = (int *)malloc(100);
     free(p);
     free(p);//重复释放
}

6. Dynamically open up memory and forget to release it (memory leak)

void test()
{
     int *p = (int *)malloc(100);
     if(NULL != p)
     {
         *p = 20;
     }
}
int main()
{
     test();
     return 0;
}

Program memory allocation:

Several areas of C/C++ program memory allocation:
1. Stack area (stack): When a function is executed, the storage units of local variables in the function can be created on the stack, and these storage units are automatically released when the function execution ends. The stack memory allocation operation is built into the instruction set of the processor, which is very efficient, but the allocated memory capacity is limited . The stack area mainly stores local variables allocated by running functions , function parameters, return data, return address, etc.
2. Heap area (heap): Generally, it is allocated and released by the programmer. If the programmer does not release it , it may be reclaimed by the OS at the end of the program. The allocation method is similar to a linked list.
3. Data segment (static area): (static) stores global variables and static data. Released by the system after the program ends .
4. Code segment: store the binary code of the function body (class member functions and global functions) .

Flexible array:

typedef struct st_type
{
        int i ;
        int a []; // flexible array member
} type_a ;
Some compilers will say that the above definition is wrong, which can be changed to:
typedef struct st_type
{
        int i ;
        int a [ 0 ]; // flexible array member
} type_a ;
1.1 A flexible array member in a structure must be preceded by at least one other member.
1.2 The size of this structure returned by sizeof does not include the memory of the flexible array.
1.3 The structure containing flexible array members uses the malloc () function to dynamically allocate memory, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array.
typedef struct st_type
{
int i ;
int a [ 0 ]; // flexible array member
} type_a ;
printf ( "%d\n" , sizeof ( type_a )); // The output is 4

Use of flexible arrays:

int i = 0;
//这样柔性数组成员a,相当于获得了100个整型元素的连续空间。
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
//业务处理
p->i = 100;
for(i=0; i<100; i++)
{
     p->a[i] = i;
}
free(p);

Advantages of flexible arrays:

The first benefit is: easy memory release
        If our code is in a function for others, you do a secondary memory allocation in it and return the entire structure to the user. The user can release the structure by calling free, but the user does not know that the members of this structure also need to be free, so you can't expect the user to find this out. Therefore, if we allocate the memory of the structure and the memory required by its members at one time, and return a pointer to the structure to the user, the user can release all the memory by doing a free once.
The second advantage is: this is conducive to access speed .
        Continuous memory is beneficial to improve access speed and reduce memory fragmentation (interval memory in the middle of the opened space is not used).

 The above is the analysis of personal learning insights and learning, welcome everyone to discuss in the comment area!

Thanks for the one-click three-connection guys! Thanks for the one-click three-connection guys! Thanks for the one-click three-connection guys!

                                              

Guess you like

Origin blog.csdn.net/weixin_71964780/article/details/132418386