Dynamic memory management (heap)

Keywords: C C++

catalogue

Why is there dynamic memory management

How to manage space?

Introduction to dynamic memory functions

malloc and free

calloc

​ realloc

Common dynamic memory errors

Written test questions

Flexible array

  Use of flexible arrays

Advantages of flexible arrays

Why is there dynamic memory management

1. You can apply for large memory for large-scale applications

2. The application can be made during the running of the program, and the memory space can be used more flexibly.

(malloc() function is used to apply for space. It can only be called when the program is running. The compilation process has already passed.)

How to manage space?

Apply for space and use through malloc function, and release space with free function

Common details:

1. Overall application and release.

2. If the requested memory is not returned, it will cause memory leakage.

Memory leak: a serious problem that causes less and less available memory.

                    When the process exits, the memory leak problem is gone.

                            The program is divided into: 1. The program that runs immediately ends and the resident program (the program that is endless and will not end). The resident program is easy to cause memory leakage.

3. The application has a size. Free didn't tell us how many bytes should be released? So how does free know how much to release? At present, the free parameter can only know where to release.

When applying, the space actually applied for will be larger than the space you want, and the larger part will be used to save the "original information" of this application

Original information: attribute information (corresponding to the size of heap space, etc.)

4. Heap space is suitable for the application of large space (because more application space is needed to save attribute information)

5. What exactly did free do?

Cancel the relationship between the address saved inside the pointer and heap space, but the value of the pointer remains unchanged. Therefore, it is recommended to set the pointer to NULL after free ing space.

Introduction to dynamic memory functions

malloc and free

Dynamic memory development function provided by C language

void* malloc(size_t size);
This function requests a block of memory Continuous availability And returns a pointer to this space.
If the development is successful, a pointer to the developed space is returned.
If the development fails, a NULL Pointer, therefore malloc The return value of must be checked.
The type of the return value is void* , so malloc The function does not know the type of open space, which is determined by the user when using it.
If parameter size by 0 , malloc The behavior of the standard is undefined and depends on the compiler. (vs2013 can).
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);
free Function is used to free dynamic memory.
If parameter ptr The space pointed to is not dynamically opened up, so free The behavior of the function is undefined.
If parameter ptr yes NULL Pointer, the function does nothing.

calloc

void* calloc(size_t num,size_t size);
The functions of this function are basically the same as malloc function. The only difference is that each byte of the requested space will be initialized to 0; (initializing each byte is equivalent to traversing the space, which takes time, and the applied space is generally used (covered), so the malloc function is generally used with high efficiency.)

 realloc

The realloc function can adjust the size of the requested memory.

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 memory starting position.

This function will also move the data in the original memory to a new location on the basis of adjusting the size of the original memory space new Space.
realloc There are two situations when adjusting memory space:
Case 1: if there is enough space after the original space, it will be adjusted on the space originally applied.
Situation II; If there is not enough space after the original space, it will directly re apply for part of the space, copy the contents of the original space to the new space, and then release the original space.

Common dynamic memory errors

1, Dereference operation on NULL pointer

void test()
{
 int *p = (int *)malloc(INT_MAX/4);
 *p = 20;//If the value of p is NULL, there is a problem
 free(p);
}
(therefore, the validity of the p pointer should be checked after applying for space)
2, Cross border access to dynamic open space
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;//Cross border access when i is 10
 }
 free(p);
}

3, free the non dynamic space

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

4, Use free to release part of the memory space (it must be applied and released as a whole)

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

5, Multiple releases of the same dynamic memory

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

6, Dynamic memory forget release (memory leak)

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

Written test questions

subject 1 :

  2. Topic 2

char *GetMemory(void) {
 char p[] = "hello world";
 return p; 
}
void Test(void) {
 char *str = NULL;
 str = GetMemory();
 printf(str);
}

The function is opened on the stack. After the function is called, it is released, so there is no return value.

Note: the free space in the computer will not empty the data (the setting data is invalid), so str still points to Hello world

It can be seen from the figure above that the function has been executed, but Hello world still exists, so why not output str?

That's because printf is also a function, and it needs to open up space on the stack to be called, so it will overwrite the space originally saved for Hello world data, so it can't be output.  

3. Topic 3:

void GetMemory(char **p, int num) {
 *p = (char *)malloc(num);
}
void Test(void) {
 char *str = NULL;
 GetMemory(&str, 100);
 strcpy(str, "hello");
 printf(str);
}

The validity of the parameters is not judged, and the space requested by malloc is not released (memory leakage may occur!!).

4. Topic 4:

void Test(void) {
 char *str = (char *) malloc(100);
 strcpy(str, "hello");
 free(str);
 if(str != NULL)
 {
 strcpy(str, "world");
 printf(str);
 }
}

After free releases the space, the str pointer is not equal to NULL, but the space can not be used. Therefore, it is generally recommended to set the pointer to NULL after space release.

Flexible array

Maybe you've never heard of it Flexible array( flflexible array ) This concept, but it does exist. C99 In the structure
The latter element is allowed to be an array of unknown size, which is called a "flexible array" member.
For example:
typedef struct st_type
{
 int i;
 int a[0];//If the flexible array member reports an error, change it to int a [];
}type_a;
Features of flexible array:
A flexible array member in a structure must be preceded by at least one other member.
The size of this structure returned by sizeof does not include the memory of the flexible array.
Structure containing flexible array members malloc () Function to dynamically allocate memory, and the allocated memory should be larger than the size of the structure to adapt to the expected size of the flexible array

For example:

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

//Code 1
int i = 0;
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
//Business processing
p->i = 100;
for(i=0; i<100; i++) {
 p->a[i] = i; }
free(p);
This allows flexible array members a , equivalent to obtaining 100 A continuous space of integer elements.

Advantages of flexible arrays

The above code can also be written as:

//Code 2
typedef struct st_type
{
 int i;
 int *p_a; }type_a;
type_a *p = malloc(sizeof(type_a));
p->i = 100; p->p_a = (int *)malloc(p->i*sizeof(int));
//Business processing
for(i=0; i<100; i++) {
 p->p_a[i] = i; }
//Free up space
free(p->p_a);
p->p_a = NULL;
free(p);
p = NULL;
above code 1 and code 2 Can do the same function, but method 1 Easy memory release
If our code is in a function for others, you make a secondary memory allocation in it and return the whole structure to the user
User call free The structure can be released, but the user does not know that the members in the structure also need to be released free , so you can't expect users to send
Now this thing. Therefore, if we allocate the memory of the structure and the memory required by its members at one time, and return a structure to the user
Pointer, the user does it once free You can free up all the memory.

Posted by seaten on Fri, 05 Nov 2021 13:30:55 -0700