[C language] How much memory do you know? Explain C language dynamic memory management in detail

 

Table of contents

First, the memory in the computer

Two, dynamic memory application function

2.1 Header file

2.2 malloc function

2.3 free function

2.3 calloc function

2.4 realloc function - adjust space function

Case 1: There is enough space after the original space

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

2.5 Classic written test questions

 1.

2. 

Three, flexible array

epilogue


First, the memory in the computer

    We know that there are currently memory, stack area, heap area, and static area.

Several areas of C/C++ program memory allocation:

  •   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.
  •   Heap area (heap): Generally allocated and released by the programmer, if the programmer does not release it, it may be reclaimed by the OS (operating system) at the end of the program. The allocation method is similar to a linked list.
  •  The data segment (static area) (static) stores global variables and static data. Released by the system after the program ends.
  •  Code segment: store the binary code of the function body (class member functions and global functions).

 Currently we have these methods of allocating memory space:

int  h  = 100;             //  在静态区创建全局变量

int main()

{

static  z  = 10;         // 变量储存在静态区

int val = 20;               //在栈空间上开辟四个字节

char arr[10] = {0};     //在栈空间上开辟10个字节的连续空间

   return 0;

}

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

1. The space allocation size is fixed.

2. When declaring an array, 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, and the way to open up space when the array is compiled cannot be satisfied. At this time, you can only try dynamic storage and development. 

Two, dynamic memory application function

2.1 Header file

#include<stdlib.h>

2.2 malloc function

void* malloc (size_t size); // szie means the number of bytes, you can directly fill in the number

The C language provides a dynamic memory allocation function:

This function applies for a continuously available random space from the memory heap area , and returns a pointer to this space.

  • If the allocation is successful, a pointer to the allocated space is returned .
  • malloc can apply for a space of 0 bytes , and will return a pointer with no space, which cannot be accessed.
  • If the opening 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 the opened space, and the user can decide by himself when using it .

 use:

int * a = (int *)malloc(4); // 4可以改成 sizeof(int)
if	(a == NULL)
{
  perror("malloc"); // 开辟失败打印原因
}

2.3 free function

void free (void* ptr);

The free function is used to release dynamically allocated memory.

  • If the space pointed to by the parameter ptr is not dynamically opened, the behavior of the free function is undefined.
  • If the parameter ptr is a NULL pointer, the function does nothing.
  • When we don't release the dynamically requested memory, if we continue to apply for memory, then the computer's memory will continue to decrease, and it will die when there is no memory. When the program ends, the operating system will automatically reclaim the memory.
  • If the program does not end, there will be more and more memory that will not be reclaimed. This is the problem of memory leaks.

2.3 calloc function

void* calloc (size_t num, size_t size);

Parameter analysis:

  • num: The number of data types to create.
  • size: The number of bytes occupied by each data type .

Features: 

  •  The function of the function is to open up a space for num elements whose size is size, and initialize each byte of the space to 0.
  • The only 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* a = (int*)malloc(8); // 2个整型
	int* b = (int*)calloc(2,sizeof(int)); // sizeof(int) 可以是 4,反正表示字节数
	return 0;
}

 View memory verification:

2.4 realloc function - adjust space function

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

Parameter analysis:

  • ptr: is the memory address to be adjusted. (If it is a null pointer, it is similar to the function of malloc.)
  • size : the new size after adjustment
  • Return value: It is the starting position of memory after adjustment.

The emergence of the realloc function makes dynamic memory management more flexible. 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 use the memory reasonably, we must make flexible adjustments to the size of the memory.

 The realloc function can adjust the size of the dynamically allocated memory. function prototype

as follows:

     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.

There are two situations when realloc adjusts the memory space:

  • Case 1 : There is enough space after the original space

  • Case 2: There is not enough space after the original space 

 

 Look at the following code and think that the code is unreasonable:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a = 10;
	int* p = &a;
	p = (int*)realloc(p, sizeof(int));
	printf("%d", *p);
	return 0;
}

 We can see that there is no judgment on whether realloc is successful or not. If the application fails and NULL is returned, then p will lose the original address, which is unreasonable, so we need to make a judgment, so the correct code is:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a = 10;
	int* p = &a;
	int *tmp= (int*)realloc(p, sizeof(int));
	if (tmp == NULL)
	{
		perror("realloc");
		return -1;// 或者exit(-1);
	}
	p = tmp;
	printf("%d", *p);
	return 0;
}

2.5 Classic written test questions

 1.

   Thinking: Program Outcomes

char* GetMemory(void)
{
	char p[] = "hello world"; // 栈区开辟,函数结束内存收回
	return p;
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();  // 非法访问。访问被系统收回的内存
	printf(str);        // 无法打印,已被覆盖
}

int main()
{
	Test();
	return 0;
}

2. 

  problems in the program

void Test(void)
{
	char* str = (char*)malloc(100); // 缺少对malloc返回值检查
	/*加上:if(str == null)
	{
		perror("malloc");
		exit(-1);
	}*/
	strcpy(str, "hello");
	free(str);      
	// 加上 str = null;
	if (str != NULL)         // str还存有原先内存的地址,出现野指针 
	{
		strcpy(str, "world");
		printf(str);
	}
}

int main()
{
	Test();
	return 0;
}

Three, flexible array

     Maybe you've never heard of the concept of flexible arrays , but they do exist. In C99, the last element in a structure 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[]; //flexible array member

}type_a;

 Features:

  • A flexible array member in a structure must be preceded by at least one other member .
  • The size of such a structure returned by sizeof does not include memory for flexible arrays.

For example: 

typedef struct mystruct
{
    double a;
    int c[];
}MS;

int main()
{
    printf("%d\n", sizeof(MS)); // 8
    return 0;
}
  • Structures containing flexible array members use the malloc() function for dynamic allocation of memory, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array.

as follows: 

typedef struct mystruct
{
    double a;
    int c[];
}MS;

int main()
{
    MS * p1 = (MS* )malloc(sizeof(MS) + 40);  // 那就是48个字节,40就是对柔性数组申请的                                                                                                                                 //预期空间
    return 0;
}

It can also be like this:

代码2
typedef struct mystruct
{
    double a;
    int *c;
}MS;
int main()
{
    MS * p1 = (MS* )malloc(sizeof(MS));  
    if  (p1 == NULL)
{
   perror ( "malloc");
   exit(-1);
}
   p1->c = (int *)realloc(c, 40);
    return 0;
}

 Advantages of Code 1 over Code 2:

  • Easy to free up memory. Code 2 needs to free memory 2 times.
  • It is conducive to improving the data hit rate, improving operating efficiency, and reducing memory fragmentation.

epilogue

   This section is over here, thank you friends for browsing, if you have any suggestions, welcome to comment in the comment area, if you bring some gains to your friends, please leave your likes, your likes and concerns will become bloggers The driving force of the master's creation .

Guess you like

Origin blog.csdn.net/qq_72112924/article/details/131343876
Recommended