Dynamic memory management and common errors

The meaning of existence

Our memory development methods are mainly:

int a=0;//开辟4字节的空间
int arr[5]={
    
    0};//开辟20字节的空间

There are several problems with this development:
Since the variable development is in the stack in the memory, the space is relatively limited.
It can only open up a fixed memory space, which is not convenient for subsequent adjustments.
In a specific scenario, we cannot obtain the memory size that needs to be opened up.

Therefore, we have dynamically opened up space to solve problems in some specific situations.

1. Unable to determine the required memory size, or a changed memory size
2. You can open up a larger space for operation (the dynamically opened memory space is on the memory heap, and the space is larger than the stack space where the variable is located)
3. But although it is very Good, but the dynamically opened memory space needs to be released actively by the person we applied for, otherwise it will cause serious memory leaks.

Memory leak can be said to be a very fatal problem, especially in some continuous running places, such as server code. In severe cases, the server will be paralyzed.

  1. 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 is executed . The stack memory allocation operation is built into the processor's instruction set, which is very efficient, but the allocated memory capacity is
    limited. The stack area mainly stores local variables, function parameters, return data, return addresses, etc. allocated for running functions.
  2. Heap: Generally allocated and released by the programmer, if the programmer does not release it, it may be reclaimed by the OS when the program ends. The allocation method is similar
    to a linked list.

related functions

1.malloc

C language provides a function for dynamic memory development:

void* malloc(size_t  size);
//size是指开辟空间的字节数

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

1. If the development is successful, a pointer to the opened space will be returned. Return NULL on failure;
2. The return value is generic, so we can decide by ourselves.
3. If the parameter size is 0, the behavior of malloc is undefined by the standard.

We generally use malloc like this:

int* arr=(int*)malloc(4);

int a[5]={
    
    0};
char* arr1=(char*)malloc(sizeof(int)*5);
//malloc搭配sizeof更方便
//malloc一般使用是带一个强制类型转换

2.free

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

void free(void*arr);

Key points:

The free function is used to release dynamically allocated memory.
1. If the space pointed to by the parameter arr is not dynamically opened up, the behavior of the free function is undefined.
2. If the parameter arr is a NULL pointer, the function does nothing.

int* arr=(int*)malloc(4);
free(arr);

int a[5]={
    
    0};
char* arr1=(char*)malloc(sizeof(int)*5);
free(arr1);

3.calloc

It is the same as malloc to open up heap memory, except that it will initialize all the opened space to 0;
there are differences between him and malloc's formal parameters, which need to be noted.

void* calloc (size_t num, size_t size);
//开辟num个大小为size字节的空间

1. The function of the function is to open a space for num elements of size size, and initialize each byte of the space to 0.
2. The difference with the function malloc is that calloc initializes each byte of the requested space to all 0s before returning the address

int *arr = calloc(10, sizeof(int));
free(arr);
//不用的时候就一定要free掉内存,虽然我们的代码很短,
//在程序结束自动释放,但是大项目就不一定了。

Insert picture description here

4.realloc

The emergence of the realloc function makes dynamic memory management more flexible.
He can change the size of the heap space we apply for.

void* realloc (void* ptr, size_t size);
//ptr 是要调整的内存地址
//size 调整之后新大小
//返回值为调整之后的内存起始位置。
int *arr = calloc(10, sizeof(int));
int *p=realloc(arr,20);
free(p);
//将calloc出来的40字节变成了20字节

Note:
There are two situations when realloc changes the size of the space:
1. The starting position of the space remains unchanged (the original space is large enough)
Insert picture description here
2. The starting position changes
Insert picture description here

Common mistakes

1. No blank

INT_MAX is a macro definition, which means that we can apply to the operating system for the maximum memory space, which cannot be completed under normal circumstances, so malloc returns NULL, and we dereference a null pointer, which is undefined behavior.

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

2. Out of bounds

Crossing the boundary is an undefined behavior. Regardless of whether it is dynamically opened or variables in the stack space, they cannot be accessed beyond the boundary.

int* arr=(int *)malloc(sizeof(int)*4);
for(int i=0;i<=4;i++){
    
    
	*(p+i)=1;
}

3. Non-dynamic development free

free only supports dynamically allocated memory, otherwise an error will be reported

int arr[5]={
    
    0};
free(arr);

4. Not fully released

Incomplete release, causing a memory leak

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

5. Repeat release

This repeated release of memory space is undefined behavior.

int *arr = calloc(10, sizeof(int));
int *p=realloc(arr,20);
free(p);
free(arr);

6. No free space

The memory space created dynamically must be released when not in use.

int* p=(int*)malloc(12);

Guess you like

Origin blog.csdn.net/zhaocx111222333/article/details/114630735